This repository has been archived by the owner on Aug 23, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
/
class.atkmetanode.inc
192 lines (176 loc) · 5.43 KB
/
class.atkmetanode.inc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
<?php
/**
* This file is part of the Achievo ATK distribution.
* Detailed copyright and licensing information can be found
* in the doc/COPYRIGHT and doc/LICENSE files which should be
* included in the distribution.
*
* @package atk
*
* @copyright (c) 2004-2007 Peter C. Verhage
* @license http://www.achievo.org/atk/licensing ATK Open Source License
*
* @version $Revision$
* $Id$
*/
atkimport("atk.atknode");
/**
* The ATK Meta Node class.
*
* Makes it possible to create nodes in 1 line of code
* using metadata from the database.
*
* @author Peter C. Verhage <[email protected]>
*
* @package atk
*/
class atkMetaNode extends atkNode
{
/**
* Meta options.
*
* @var array
*/
private $m_metaOptions;
/**
* Constructor.
*
* This constructor accepts a variety of parameters in different order.
* To make this possible (and for supporting passing parameters by reference)
* the constructor accepts an array which may contain the following fields:
*
* - type node type
* - table table name
* - sequence sequence name to use (if not specified, it'll use autoincrement for mysql)
* - db/database database name or instance
* - policy meta policy, the meta policy to use ((sub-)class atkMetaPolicy instance)
* - grammar meta grammar, the meta grammar to use ((sub-)class atkMetaGrammar instance)
* - compiler meta compiler, the meta compiler to use ((sub-)class atkMetaCompiler instance)
* - handler meta handler, handler which needs to be called instead of the default meta method
* - flags node flags
* - descriptor descriptor template for this node
* - order (default) order to sort fields
* - index create indexed navigation on a attribute/fieldname
* - filter filter
* - securityAlias security alias for this node
* - securityMap security map for this node (will be added to the existing security map!)
* - cacheable control whatever this meta node is cacheable (by default a metanode is
* cachable if the meta method is defined static or if there is no meta method
* defined)
*
* All of these variables can also be specified by creating a class variable with
* the same name. If you do so for flags, and have to use multiple flags, use
* an array of flags.
*
* @param array $options meta node options
*
* @return atkMetaNode
*/
public function __construct($options=array())
{
$this->m_metaOptions = $options;
$type = $this->getMetaOption('type', strtolower(get_class($this)));
parent::__construct($type);
if (!$this->_constructFromCache())
$this->_constructFromPolicy();
$this->postMeta();
}
/**
* Old-style constructor for backwards-compatibility.
*
* @return atkMetaNode
*/
protected function atkMetaNode()
{
$args = func_get_args();
call_user_func_array(array($this, '__construct'), $args);
}
/**
* Returns the value for the meta option with the given name.
*
* @param string $name meta option name
* @param mixed $default fallback value
*
* @return mixed meta option value
*/
public function getMetaOption($name, $default=null)
{
if (isset($this->$name))
{
return $this->$name;
}
else if (isset($this->m_metaOptions[$name]))
{
return $this->m_metaOptions[$name];
}
else
{
return $default;
}
}
/**
* Is the node structure cacheable?
*
* @return boolean cacheable?
*/
public function isCacheable()
{
$cacheable = $this->getMetaOption('cacheable');
if ($cacheable !== null) return $cacheable;
if (!atkconfig('meta_caching', true)) return false;
if (strtolower(get_class($this)) == 'atkmetanode') return false;
if (!method_exists($this, 'meta')) return true;
$method = new ReflectionMethod(get_class($this), 'meta');
return $method->isStatic();
}
/**
* Constructs the meta node from the cache if this node is cachable and the node
* structure has been cached.
*
* @return boolean is the node constructed from the cache?
*/
private function _constructFromCache()
{
if (!$this->isCacheable()) return false;
atkimport('atk.utils.atktmpfile');
$file = new atkTmpFile("meta/".$this->getModule()."/".$this->getType().".php");
$module = getModule($this->getModule());
if ($file->exists() && ($module == null || !file_exists($module->getNodeFile($this->atkNodeType())) || filemtime($file->getPath()) > filemtime($module->getNodeFile($this->atkNodeType()))))
{
$node = $this;
include($file->getPath());
return true;
}
return false;
}
/**
* Create policy.
*
* @return atkMetaPolicy policy
*/
protected function _createPolicy()
{
atkimport('atk.meta.atkmetapolicy');
$policy = $this->getMetaOption('policy');
return atkMetaPolicy::create($this, $policy);
}
/**
* Constructs the meta node using the meta policy.
*/
protected function _constructFromPolicy()
{
$policy = $this->_createPolicy();
$policy->apply();
}
/**
* Post meta.
*
* This method is called just after the node is constructed from the cache
* or using the meta policy and allows you to do some node initialization
* which cannot be done by the meta policy.
*/
public function postMeta()
{
// do nothing
}
}