markstory / story-scribbles

MIT licensed pieces

This URL has Read+Write access

story-scribbles / cakephp / shells / aco_sync.php
ed4bc230 » markstory 2008-09-13 Adding in AcoSync Shell 1 <?php
2 /**
3 * Aco Shell.
4 *
5 * Automates the creation of ACO nodes for CakePHP applications.
6 *
7 * Copyright 2008, Mark Story.
8 * 823 millwood rd.
9 * toronto, ontario M4G 1W3
10 *
11 * Licensed under The MIT License
12 * Redistributions of files must retain the above copyright notice.
13 *
14 * @copyright Copyright 2008, Mark Story.
15 * @link http://mark-story.com
16 * @version 0.5
17 * @author Mark Story <mark@mark-story.com>
18 * @license http://www.opensource.org/licenses/mit-license.php The MIT License
19 */
20 App::import('Component', 'Acl');
21 App::import('Model', 'DbAcl');
22 /**
23 * Shell for ACO sync
24 *
25 * @package cake
26 * @subpackage cake.cake.console.libs
27 */
28 class AcoSyncShell extends Shell {
29 /**
30 * Contains instance of AclComponent
31 *
32 * @var object
33 * @access public
34 */
35 var $Acl;
36 /**
37 * Contains arguments parsed from the command line.
38 *
39 * @var array
40 * @access public
41 */
42 var $args;
43 /**
44 * Contains database source to use
45 *
46 * @var string
47 * @access public
48 */
49 var $dataSource = 'default';
50
51 /**
52 * Root node name.
53 *
54 * @var string
55 **/
56 var $rootNode = 'controllers';
57
58 /**
59 * Internal Clean Actions switch
60 *
61 * @var boolean
62 **/
63 var $_clean = false;
64
65 /**
66 * Start up And load Acl Component / Aco model
67 *
68 * @return void
69 **/
70 function startup() {
71 $this->Acl =& new AclComponent();
72 $controller = null;
73 $this->Acl->startup($controller);
74 $this->Aco =& $this->Acl->Aco;
75 }
76
77 /**
78 * Override main() for help message hook
79 *
80 * @access public
81 */
82 function main() {
83 $out = __("Available ACO sync commands:", true) . "\n";
84 $out .= "\t - update\n";
85 $out .= "\t - sync\n";
86 $out .= "\t - help\n\n";
87 $out .= __("For help, run the 'help' command. For help on a specific command, run 'help <command>'", true);
88 $this->out($out);
89 }
90
91 /**
92 * undocumented function
93 *
94 * @return void
95 **/
e10b7fba » markstory 2008-10-17 Adding acl_extras shell, ad... 96 function update() {
ed4bc230 » markstory 2008-09-13 Adding in AcoSync Shell 97 $root = $this->_checkNode($this->rootNode, $this->rootNode, null);
98 App::import('Core', array('Controller'));
99
100 $Controllers = Configure::listObjects('controller');
101 $appIndex = array_search('App', $Controllers);
102 if ($appIndex !== false ) {
103 unset($Controllers[$appIndex]);
104 }
105 // look at each controller in app/controllers
106 foreach ($Controllers as $ctrlName) {
107 App::import('Controller', $ctrlName);
108 // find / make controller node
109 $controllerNode = $this->_checkNode($this->rootNode .'/'.$ctrlName, $ctrlName, $root['Aco']['id']);
110 $this->_checkMethods($ctrlName, $controllerNode, $this->_clean);
111 }
112 if ($this->_clean) {
113 $this->Aco->id = $root['Aco']['id'];
114 $controllerNodes = $this->Aco->children(null, true);
115 $ctrlFlip = array_flip($Controllers);
116 foreach ($controllerNodes as $ctrlNode) {
117 if (!isset($ctrlFlip[$ctrlNode['Aco']['alias']])) {
118 $this->Aco->id = $ctrlNode['Aco']['id'];
119 if ($this->Aco->delete()) {
120 $this->out(sprintf(__('Deleted %s and all children', true), $this->rootNode . '/' . $ctrlNode['Aco']['alias']));
121 }
122 }
123 }
124 }
125 $this->out(__('Aco Update Complete', true));
126 return true;
127 }
128
129 /**
130 * Sync the ACO table
131 *
132 * @return void
133 **/
134 function sync() {
135 $this->_clean = true;
e10b7fba » markstory 2008-10-17 Adding acl_extras shell, ad... 136 $this->update();
ed4bc230 » markstory 2008-09-13 Adding in AcoSync Shell 137 }
138
139 /**
140 * Check a node for existance, create it if it doesn't exist.
141 *
142 * @param string $path
143 * @param string $alias
144 * @param int $parentId
145 * @return array Aco Node array
146 */
147 function _checkNode($path, $alias, $parentId = null) {
148 $node = $this->Aco->node($path);
149 if (!$node) {
150 $this->Aco->create(array('parent_id' => $parentId, 'model' => null, 'alias' => $alias));
151 $node = $this->Aco->save();
152 $node['Aco']['id'] = $this->Aco->id;
153 $this->out(sprintf(__('Created Aco node: %s', true), $path));
154 } else {
155 $node = $node[0];
156 }
157 return $node;
158 }
159
160 /**
161 * Check and Add/delete controller Methods
162 *
163 * @param string $controller
164 * @param array $node
165 * @param bool $cleanup
166 * @return void
167 */
168 function _checkMethods($controller, $node, $cleanup = false) {
169 $className = $controller . 'Controller';
170 $baseMethods = get_class_methods('Controller');
171 $actions = get_class_methods($className);
172 $methods = array_diff($actions, $baseMethods);
173 foreach ($methods as $action) {
a382dee2 » markstory 2008-09-15 Adding private method detec... 174 if (strpos($action, '_', 0) === 0) {
175 continue;
176 }
ed4bc230 » markstory 2008-09-13 Adding in AcoSync Shell 177 $this->_checkNode($this->rootNode . '/' . $controller . '/' . $action, $action, $node['Aco']['id']);
178 }
179 if ($cleanup) {
180 $actionNodes = $this->Aco->children($node['Aco']['id']);
181 $methodFlip = array_flip($methods);
182 foreach ($actionNodes as $action) {
183 if (!isset($methodFlip[$action['Aco']['alias']])) {
184 $this->Aco->id = $action['Aco']['id'];
185 if ($this->Aco->delete()) {
186 $path = $this->rootNode . '/' . $controller . '/' . $action['Aco']['alias'];
187 $this->out(sprintf(__('Deleted Aco node %s', true), $path));
188 }
189 }
190 }
191 }
192 return true;
193 }
194
195
196 /**
197 * Show help screen.
198 *
199 * @access public
200 */
201 function help() {
202 $head = __("Usage: cake aco_sync <command>", true) . "\n";
203 $head .= "-----------------------------------------------\n";
204 $head .= __("Commands:", true) . "\n\n";
205
206 $commands = array(
207 'update' => "\tcake aco_sync update\n" .
208 "\t\t" . __("Add new ACOs for new controllers and actions", true) . "\n" .
209 "\t\t" . __("Create new ACO's for controllers and their actions. Does not remove any nodes from ACO table", true),
210
211 'sync' => "\tcake aco_sync sync\n" .
212 "\t\tPerform a full sync on the ACO table.\n" .
213 "\t\t" . __("Creates new ACO's for missing controllers and actions. Removes orphaned entries in the ACO table.", true) . "\n",
214
215 'help' => "\thelp [<command>]\n" .
216 "\t\t" . __("Displays this help message, or a message on a specific command.", true) . "\n"
217 );
218
219 $this->out($head);
220 if (!isset($this->args[0])) {
221 foreach ($commands as $cmd) {
222 $this->out("{$cmd}\n\n");
223 }
224 } elseif (isset($commands[low($this->args[0])])) {
225 $this->out($commands[low($this->args[0])] . "\n");
226 } else {
227 $this->out(sprintf(__("Command '%s' not found", true), $this->args[0]));
228 }
229 }
230 }
231 ?>