CMS  Version 3.9
upgrade_manager.inc
Go to the documentation of this file.
1 <?php
7 /**************************************************************
8 
9  Copyright (c) 2010 Sonjara, Inc
10 
11  Permission is hereby granted, free of charge, to any person
12  obtaining a copy of this software and associated documentation
13  files (the "Software"), to deal in the Software without
14  restriction, including without limitation the rights to use,
15  copy, modify, merge, publish, distribute, sublicense, and/or sell
16  copies of the Software, and to permit persons to whom the
17  Software is furnished to do so, subject to the following
18  conditions:
19 
20  The above copyright notice and this permission notice shall be
21  included in all copies or substantial portions of the Software.
22 
23  Except as contained in this notice, the name(s) of the above
24  copyright holders shall not be used in advertising or otherwise
25  to promote the sale, use or other dealings in this Software
26  without prior written authorization.
27 
28  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
29  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
30  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
31  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
32  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
33  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
34  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
35  OTHER DEALINGS IN THE SOFTWARE.
36 
37 *****************************************************************/
38 
39 /*
40  * Parent class for component upgrade management.
41  *
42 
43  *
44  * To add self-updating to a component, follow these
45  * steps:
46  *
47  * 1) create the schema file:
48  *
49  * default sqlFile name is component_name + _schema.sql
50  *
51  * e.g. for component "program", the file name would be
52  * program_schema.sql
53 
54 -----------
55 
56 -- Fakoli MyComponentName Schema
57 --
58 -- Each version update must begin with the following:
59 -- START Version xx
60 -- and end with
61 -- END Version xx
62 
63 -- START Version 1.0
64 -- Do not include statement to Drop table if exists.
65 -- If the table exists, we should not be running this
66 -- sql.
67 
68 -- END Version 1.0
69 
70 
71 -----------
72 
73  * 2) In the component's manifest file, subscribe to event
74  * "upgradeComponent".
75 
76 ------------
77  static function subscribeToEvents()
78  {
79  return array(
80  "upgradeComponent" => array(MyComponentManager, upgradeComponent)
81  );
82  }
83 -------------
84 
85  * 3) In your manager class, add the function:
86 
87 -------
88  static function upgradeComponent($version)
89  {
90  $mgr = new MyComponentUpgradeManager();
91  $mgr->upgrade($version);
92  }
93 -------
94  * 4) Create the class MyComponentUpgradeManager:
95  * Example: comment component
96 
97 -------
98 Fakoli::using("mycomponent", "component");
99 
100 class MyComponentUpgradeManager extends UpgradeManager
101 {
102  var $updateMap = array(
103  "1.0" => "sql:Initial Installation"
104  );
105 
106  function MyComponentUpgradeManager()
107  {
108  $this->component_name = "mycomponent";
109 
110  // sets the sqlFile name according to default
111  parent::UpgradeManager();
112  }
113 }
114 -------
115 
116  *
117  * To upgrade the component's data schema or
118  * run a data update, child classes enter the
119  * new version in the updateMap as the array key and the
120  * update handler as the value.
121  *
122  * Version numbers are the array index in the updateMap -
123  * list version numbers in ascending order.
124  *
125  * For the array value, a colon separates the update handler
126  * type from the description (e.g., "sql:my description of my update").
127  *
128  * Update Handler Types:
129  *
130  * 1) sql - use when only sql statements in the schema file
131  * are needed to upgrade the component.
132  *
133  * 2) function name (e.g., update_1_1) - use when
134  * The update handler is a custom function which you will
135  * write in your component's upgrade manager class.
136  * Example:
137  *
138 -----------------
139 
140  function update_1_1($version_number)
141  {
142  if(!$this->executeVersionSql($version_number))
143  return false;
144 
145  $pages = Query::create(Page, "WHERE published=1")->execute();
146  $pageList = formatItems($pages, "'{identifier}'", ",");
147 
148  $cPages = Query::create(ComponentPage, "WHERE enabled=1 AND identifier NOT IN ($pageList)")->execute();
149 
150  $this->addSectionContent($cPages);
151 
152  return true;
153  }
154 ---------------------
155 
156 
157  *
158  * Update functions must return true if successful so
159  * that the update is saved to the log.
160  *
161  * 3) done - use this handler type when sql updates are made
162  * locally or have already been made (as in the case of existing
163  * custom web site components, e.g., STEM2Stern programs) you can
164  * use he syntax "done" in place of "sql", then run component scan
165  * to record the update to the ComponentUpdateLog without running
166  * the sql (which has already been run). For local only "done",
167  * remember to change the handler back to "sql" before uploading
168  * the file so that the updates are run on other sites.
169  *
170  * Example:
171  * var $updateMap = array(
172  * "1.0" => "sql:Initial Installation",
173  * "1.1" => "update_1_1:separate name field into first and last names",
174  * "1.2" => "sql:add field activity_duration to program table"
175  * );
176  *
177  *
178  * Use of the Log File:
179  *
180  * The $log is used to store details of the upgrade when the
181  * handler is a custom function.
182  *
183  * For example, a function to create missing ledger records might
184  * write the following details to $this->log:
185  * $this->log .= $xrefPurchase->format("Creating purchase record: registration id: {$xref->conference_participant_xref_id} transaction_id {transaction_id} participant_id {participant_id} conference_id {conference_id} amount {amount} transaction_type {transaction_type} product_code {product_code}\r\n");
186  * The upgrade manager will create a log file with the contents of $this->log
187  * and store it in the component_update_log record so it can be downloaded
188  * and reviewed, if needed.
189 */
190 
191 abstract class UpgradeManager
192 {
193  var $sqlFile;
194  var $xmlDir;
196  var $log; // output from update functions to store in log file;
197 
198  /*
199  * Set sqlFile name as component name + "_schema.sql".
200  * First check custom app for match; if not, then check
201  * Fakoli. Custom components take precedence over
202  * Fakoli (e.g., custom user component over Fakoli's user component.
203  */
204  function UpgradeManager()
205  {
206  global $config;
207 
208  $path = ComponentManager::findComponentPath($this->component_name);
209  $this->sqlFile = $path . DIRECTORY_SEPARATOR . $this->component_name . "_schema.sql";
210  $this->xmlDir = $path . DIRECTORY_SEPARATOR . "updates";
211  }
212 
213 
214  /*
215  * Retrieve the highest component version number listed
216  * for this component in the ComponentUpdateLog.
217  *
218  * Loop through the updateMap, the history of
219  * updates provided by the component's child class
220  * update manager, and check the latest version
221  * against each one. If the latest version is less
222  * than the update, then execute the update and save
223  * the record of this update in the ComponentUpdateLog
224  * table.
225  */
226  function upgrade($upgrade_to = "")
227  {
228  if ($upgrade_to)
229  {
230  ComponentManager::scanTrace("Upgrading {$this->component_name} to version $upgrade_to", 2);
231  }
232 
233  $latest_version = ComponentUpdateLog::getLatestVersion($this->component_name);
234  ComponentManager::scanTrace("UpgradeManager:: upgrade: latest version in db for component {$this->component_name} is $latest_version", 3);
235 
236  if(count($this->updateMap) > 0)
237  {
238  foreach($this->updateMap as $version_number => $handler)
239  {
240  // remove any contents from a previous upgraded version
241  $this->log = "";
242  if($latest_version < $version_number)
243  {
244  list($function, $description) = explode(":", $handler);
245  if($this->upgradeOneVersion($version_number, $function))
246  $this->recordUpdate($version_number, $description);
247  else
248  break;
249  }
250 
251  if ($upgrade_to != "" && $upgrade_to == $version_number) break;
252  }
253  }
254 
255  // Save the latest version number to the version
256  // field of the component record
257  ComponentManager::setComponentVersion($this->component_name);
258  }
259 
260  /*
261  * If the update is just sql, then parse the
262  * sql file for the updates in the version number's
263  * section.
264  *
265  * If the update handler is "done", then just return
266  * true.
267  *
268  * If the handler is a custom functionin the child
269  * class, then execute that function.
270  */
271  function upgradeOneVersion($version_number, $function)
272  {
273  if($function == "sql")
274  return $this->executeVersionSql($version_number);
275  else if ($function == "xml")
276  return $this->executeVersionXML($version_number);
277  elseif($function != "done")
278  {
279  $updater = array($this, $function);
280  return call_user_func($updater, $version_number);
281  }
282  else // sql update done in local copy
283  return true;
284  }
285 
286  /*
287  * Execute the section of the component's sql update file
288  * that relations to the specified version number.
289  *
290  * $version_number - the version number that identifies
291  * the block of sql in the file to be executed.
292  * e.g., "1.1"
293  *
294  * The sql file should have the commented markers:
295  *
296  * -- START version 1.1
297  * ... sql statements
298  * -- END version 1.1
299  */
300  function executeVersionSql($version_number)
301  {
302  ComponentManager::scanTrace("** Upgrade {$this->component_name} to Version $version_number", 2);
303 
304  $lines = array();
305  if(!file_exists($this->sqlFile))
306  {
307  ComponentManager::scanTrace("UpgradeManager:: sql file does not exists {$this->sqlFile}", 2);
308  return;
309  }
310 
311  $fp = fopen($this->sqlFile, 'r');
312  $version_id = str_ireplace(".", "\\.", "version " . $version_number); // case insensitive
313  trace("UpgradeManager::version id: $version_id file $this->sqlFile", 3);
314 
315  if(!$fp)
316  {
317  ComponentManager::scanTrace("Error: executeVersionSql failed to open file", 2);
318  return;
319  }
320 
321  while (($buffer = fgets($fp)) !== false && !preg_match("/^--.*?\s+$version_id/i", $buffer))
322  continue;
323 
324  // Found start of this verson's update section in the sql file
325  if(preg_match("/^--\s*START\s*$version_id/i", $buffer))
326  {
327  while(($buffer = fgets($fp)) !== false && !preg_match("/^--\s*END\s*$version_id/i", $buffer))
328  {
329  $depends = array();
330  if (preg_match('/^--\s*Depends\s+On\s+([\w_]+)\s+(.*)/i', $buffer, $depends))
331  {
332  ComponentManager::scanTrace("{$this->component_name} $version_id is dependent on {$depends[1]} {$depends[2]}", 2);
333 
334  UpgradeManager::upgradeComponentToVersion($depends[1], trim($depends[2]));
335  }
336 
337  // Omit blank lines and comments
338  if(trim($buffer) == "" || preg_match("/^--(.*?)\s/", $buffer))
339  continue;
340  $lines[] = $buffer;
341  }
342 
343  trace("** Upgrade has ".count($lines)." lines", 3);
344  }
345 
346  $sqlStatements = $this->parseSQLStatements($lines);
347 
348  if(count($sqlStatements) == 0)
349  {
350  ComponentManager::scanTrace("UpgradeManager:: no query statements found for version $version_number", 3);
351  return true;
352  }
353 
354  try
355  {
356  $rtn = $this->executeSQLStatements($sqlStatements);
357  return rtn;
358  }
359  catch(Exception $e)
360  {
361  ComponentManager::scanTrace("Failed to upgrade {$this->component_name} to version $version_number - ". $e->getMessage(), 2);
362  throw new FakoliException("Failed to upgrade {$this->component_name} to version $version_number - ". $e->getMessage());
363  }
364  }
365 
366  /*
367  * Create an array of valid sql statements
368  * by scanning for ";"
369  */
370  function parseSQLStatements($lines)
371  {
372  if(count($lines) == 0)
373  return;
374 
375  $delimiter = ";";
376  foreach($lines as $line)
377  {
378  $d = array();
379 
380  ComponentManager::scanTrace("UpgradeManager:: processing update schema line $line", 4);
381  if (preg_match("/^\s*DELIMITER\s+(.*?)$/i", $line, $d))
382  {
383  $delimiter = preg_quote($d[1]);
384  //$sqlStatement .= $line."\n";
385  }
386  else
387  {
388  if(preg_match("/{$delimiter}\s*$/", $line))
389  {
390  $sqlStatement .= preg_replace("/{$delimiter}\s*$/", "", $line);
391  $sqlStatements[] = $sqlStatement;
392  $sqlStatement = "";
393  }
394  else
395  {
396  $sqlStatement .= $line;
397  }
398  }
399  }
400  trace(print_r($sqlStatements, true), 3);
401  return $sqlStatements;
402  }
403 
404  function executeSQLStatements($sqlStatements)
405  {
406  try
407  {
408  trace("Executing SQL Statements", 2);
409 
410  $db = ConnectionManager::getConnection();
411  $db->beginTransaction();
412 
413  foreach($sqlStatements as $sqlStatement)
414  {
415  trace($sqlStatement, 2);
416  $db->exec($sqlStatement);
417  }
418 
419  $db->commit();
420  fclose($fp);
421  }
422  catch(PDOException $e)
423  {
424  $db->rollBack();
425  fclose($fp);
426  throw $e;
427  }
428 
429  return true;
430  }
431 
432  function log($text)
433  {
434  if(preg_match("/(<br>|<br\/>)$/i", $text))
435  $this->log .= preg_replace(array("/<br>$/i", "/<br\/>$/i"), "\r\n", $text);
436  else
437  $this->log .= $text . "\r\n";
438  }
439 
440  function executeVersionXML($version)
441  {
442  global $config;
443 
444  ComponentManager::scanTrace("** Upgrade {$this->component_name} to Version $version_number", 3);
445 
446  if (preg_match("/\\b{$this->component_name}\\b/", $config["ignore_xml_updates"]))
447  {
448  ComponentManager::scanTrace("** Ignoring this upgrade as specified in config", 3);
449  return true;
450  }
451 
452  if (!is_dir($this->xmlDir))
453  {
454  throw new FakoliException("XML update directory does not exists for {$this->component_name}");
455  }
456 
457  $file = $this->xmlDir . DIRECTORY_SEPARATOR . $this->component_name ."_" . $version . ".xml";
458 
459  if (!file_exists($file))
460  {
461  throw new FakoliException("No XML update for version $version of $this->component_name");
462  }
463 
464  $xml = file_get_contents($file);
465  $mgr = new SerializationManager();
466  $mgr->importAll($xml);
467 
468  return true;
469  }
470 
471  function recordUpdate($version, $description)
472  {
473  if($this->log)
474  $fileName = $this->saveLogFile($version);
475  ComponentUpdateLog::recordUpdate($this->component_name, $version, $description, $fileName);
476  }
477 
478  function saveLogFile($version)
479  {
480  $upgradePath = Settings::getValue("component", "upgrade_output_path");
481 
482  $fileName = $this->component_name . "_" . $version . ".txt";
483  $fp = fopen($upgradePath . DIRECTORY_SEPARATOR . $fileName, 'w');
484  fwrite($fp, $this->log);
485  fclose($fp);
486  return $fileName;
487  }
488 
489 
514  function addSectionContent($items, $section_name = "/", $role = "", $template = "", $permissions = "")
515  {
516  if($items && !is_array($items))
517  $items = array($items);
518 
519  if(count($items) == 0)
520  {
521  trace("No items found to add to section", 2);
522  return true;
523  }
524 
525  $sections = Query::create(Section, "WHERE section=:section")
526  ->bind(":section", $section_name)
527  ->execute();
528 
529  if(count($sections) == 0)
530  {
531  trace("UpgradeManager::addSectionContent - section $section_name not found", 3);
532  return false;
533  }
534  else
535  $section = $sections[0];
536 
537  foreach($items as $item)
538  {
539  if (is_object($item))
540  {
541  $ident = $item->identifier;
542  }
543  else
544  {
545  $ident = $item;
546  }
547 
548  // should be only one or none
549  $contents = Query::create(SectionContent, "WHERE identifier=:identifier AND section_id=:section_id")
550  ->bind(":identifier", $ident, ":section_id", $section->section_id)
551  ->execute();
552 
553  $content = (count($contents) > 0) ? $contents[0] : null;
554 
555  if(!$content)
556  {
557  $content = new SectionContent();
558  $content->section_id = $section->section_id;
559  $content->identifier = $ident;
560  }
561  else
562  {
563  $content->filter = new InclusionFilter("template", "role");
564  }
565 
566  if($section->default_template != $template)
567  $content->template = $template;
568  if($section->default_role != $role)
569  $content->role = $role;
570  if ($section->default_permissions != $permissions)
571  $content->permissions = $permissions;
572 
573  $content->save();
574 
575  trace("Added $item to $section_name", 3);
576  }
577 
578  return true;
579  }
580 
581 
588  function addModuleToPages($items, $module_name, $position = 'right', $sort_order = 1)
589  {
590  if($items && !is_array($items))
591  $items = array($items);
592 
593  if(count($items) == 0)
594  return true;
595 
596  $modules = Query::create(Module, "WHERE title=:title")
597  ->bind(":title", $module_name)
598  ->execute();
599 
600  if(count($modules) == 0)
601  return false;
602  else
603  $module = $modules[0];
604 
605  foreach($items as $item)
606  {
607  if(!is_object($item))
608  {
609  $page = $this->searchByIdentifier($item);
610  if(!$page) return false;
611  }
612  else
613  $page = $item;
614 
615  $xref_class = (preg_match("/component/i", (get_class($page)))) ? ComponentPageModuleXref : PageModuleXref;
616  $xref = new $xref_class();
617  $pk = $page->getPrimaryKey();
618 
619  $found = Query::create($xref_class, "WHERE $pk=:$pk AND module_id=:module_id")
620  ->bind(":$pk", $page->$pk, ":module_id", $module->module_id)
621  ->executeValue("COUNT(1)");
622 
623  if(!$found)
624  {
625  $xref->$pk = $page->$pk;
626  $xref->module_id = $module->module_id;
627  $xref->position = $position;
628  $xref->sort_order = $sort_order;
629  $xref->save();
630  $this->log .= $page->format("Adding $xref_class record for page {identifier} to module {$module->title}\r\n");
631  }
632  else
633  {
634  $this->log .= "Page identifier $identifier already linked to module {$module->title}\r\n";
635  }
636  }
637 
638  return true;
639  }
640 
641  /*
642  * We don't use "findByIdentifier" because would
643  * crash if not found.
644  */
646  {
647  $pages = Query::create(Page, "WHERE identifier=:identifier")
648  ->bind(":identifier", $identifier)
649  ->execute();
650 
651  if(count($pages) == 0)
652  {
653  $pages = Query::create(ComponentPage, "WHERE identifier=:identifier")
654  ->bind(":identifier", $identifier)
655  ->execute();
656  }
657 
658  if(count($pages) == 0)
659  {
660  $this->log .= "Page identifier $identifier not found in Page or ComponentPage tables\r\n";
661  }
662 
663  return (count($pages) > 0) ? $pages[0] : null;
664  }
665 
666  /*
667  * @item - page of class CMS Page, Component Page,
668  * Calendar, etc. If an identifier is sent, it must
669  * be of class CMS Page or Component Page.
670  * We need the full object b/c we need to set the menu
671  * item's role using the object's roles
672  *
673  * @menu_identifier - identifier of menu in table "menu" to which the item should be
674  * added (e.g., "personnel_subnav", "global")
675  *
676  * @parent_identifier - the identifier of the menu_item in menu_item table
677  * under which this menu item should be added - empty if top level
678  *
679  * @title - the title to give to the menu item, if not supplied
680  * then prettify the identifier
681  *
682  * @section_name - the identifier of the section that belongs in
683  * the url path to the page from this menu item. If not supplied,
684  * the default is the the identifier of the first section the page
685  * is linked to in section_content. This function uses the section
686  * to build the url field stored with the menu item in the format:
687  * section / page identifier (e.g., /global/programs).
688  *
689  * @sort_order - the desired sort order for this item; if empty
690  * then set to bottom.
691  *
692  */
693  function addMenuItem($item, $menu_identifier, $parent_identifier = "", $title = "", $section_name = "", $sort_order = 0)
694  {
695  // Find the menu
696  $menus = Query::create(Menu, "WHERE identifier=:identifier")
697  ->bind(":identifier", $menu_identifier)
698  ->execute();
699 
700  if(count($menus) == 0)
701  return false;
702  else
703  $menu = $menus[0];
704 
705  if(!is_object($item))
706  {
707  $page = $this->searchByIdentifier($item);
708  if(!$page) return false;
709  }
710  else
711  $page = $item;
712 
713  $found = Query::create(MenuItem, "WHERE (identifier=:identifier OR url like '%{$page->identifier}') AND menu_id=:menu_id")
714  ->bind(":identifier", $page->identifier, ":menu_id", $menu->menu_id)
715  ->executeValue("COUNT(1)");
716 
717  if($found)
718  {
719  $this->log .= "Page identifier {$page->identifier} already linked to menu {$menu_identifier}\r\n";
720  return true;
721  }
722 
723  $parent_id = 0;
724 
725  if($parent_identifier)
726  {
727  $parents = Query::create(MenuItem, "WHERE identifier=:identifier")
728  ->bind(":identifier", $parent_identifier)
729  ->execute();
730 
731  if(count($parents) > 0)
732  $parent_id = $parents[0]->menu_item_id;
733  }
734 
735  if(!$sort_order)
736  {
737  $sort_order = (Query::create(MenuItem, "WHERE menu_id=:menu_id AND parent_id=:parent_id")
738  ->bind(":menu_id", $menu->menu_id, ":parent_id", $parent_id)
739  ->executeValue("MAX(sort_order)") + 1);
740  }
741 
742  if(!$section_name)
743  {
744  $sections = Query::create(SectionContent, "WHERE identifier=:identifier")
745  ->bind(":identifier", $page->identifier)
746  ->execute();
747 
748  if(count($sections) == 0)
749  {
750  trace("UpgradeManager error: page {$page->identifier} is not in section content", 3);
751  return false;
752  }
753 
754  $section_name = $sections[0]->Section()->section;
755  }
756 
757  $menuItem = new MenuItem();
758  $menuItem->title = ($title) ? $title : prettify($page->identifier);
759  $menuItem->menu_id = $menu->menu_id;
760  $menuItem->parent_id = $parent_id;
761  $menuItem->published = 1;
762  $menuItem->url = "/" . $section_name . "/" . $page->identifier;
763  $menuItem->role = $page->role;
764  $menuItem->identifier = $page->identifier;
765  $menuItem->sort_order = $sort_order;
766  $menuItem->page_id = 0;
767  $menuItem->save();
768 
769  $this->log .= $page->format("Adding menu item {identifier} to menu {$menu->name}\r\n");
770 
771  return true;
772  }
773 
774  /*
775  * reformat a string phone field to remove
776  * nondigits so that it can use the PhoneFieldRenderer
777  *
778  * @param item - obj of DataItem class
779  *
780  * @param field - field name to reformat
781  */
782  function reformatPhone(&$item, $field)
783  {
784  $oldPhone = $item->$field;
785  if(!$oldPhone)
786  return;
787 
788  // remove the 1 before 800 or 888
789  $phone = preg_replace("/^1-/","", $oldPhone);
790  // remove all nondigits
791  $phone = preg_replace("/\D/","", $phone);
792 
793  if($phone != $oldPhone)
794  {
795  $item->$field = $phone;
796  $table = $item->table;
797  $pk = $item->getPrimaryKey();
798  $this->log($item->format("Setting {$item->table} {$pk} $field from {$oldPhone} to {$phone}"));
799  $item->filter = new InclusionFilter($field);
800  $item->save();
801  }
802  }
803 
804  /*
805  * Use this function to execute sql in a file
806  * that is not the main compoennt's sql schema file.
807  * Needed when the data is too large to paste into the
808  * schema file.
809  *
810  * @param sqlFile - full path to sqlFile. File can only contain
811  * "-- " style for comments, not "/*"
812  *
813  * @param - version_number - the version number of the calling
814  * update function
815  */
816  function executeSQLFile($sqlFile, $version_number)
817  {
818  trace("** Upgrade {$this->component_name} to version $version_number by executing file {$sqlFile}", 3);
819 
820  if(!file_exists($sqlFile))
821  {
822  trace("UpgradeManager:: sql file does not exists {$sqlFile}", 2);
823  return;
824  }
825 
826  $fp = fopen($sqlFile, 'r');
827 
828  if(!$fp)
829  {
830  trace("Error: executeVersionSql failed to open file", 3);
831  return;
832  }
833 
834  $lines = array();
835  while(($buffer = fgets($fp)) !== false)
836  {
837  // Omit blank lines and comments
838  if(trim($buffer) == "" || preg_match("/^--(.*?)\s/", $buffer))
839  continue;
840  $lines[] = $buffer;
841  }
842 
843  if(count($lines) == 0)
844  {
845  trace("UpgradeManager:: no lines parsed in file {$sqlFile}", 3);
846  return true;
847  }
848 
849  $sqlStatements = $this->parseSQLStatements($lines);
850 
851  if(count($sqlStatements) == 0)
852  {
853  trace("UpgradeManager:: no query statements found in sql file {$sqlFile} for version $version_number", 3);
854  return true;
855  }
856 
857  return $this->executeSQLStatements($sqlStatements);
858  }
859 
860  function dependsOn($component, $version)
861  {
863  }
864 
865  static function upgradeComponentToVersion($component, $version)
866  {
867  trace("Firing upgrade event to $component, target version $version", 3);
868  ComponentManager::fireEventTo("upgradeComponent", $component, $version);
869  }
870 }?>
$handler
Definition: event_form.inc:62
$section
Definition: event_form.inc:44
$page
Definition: help.inc:39
$component
Definition: help.inc:38
if(! $page) $path
Definition: page.inc:57
$menu
Definition: menu_form.inc:47
$menuItem
$file
Definition: delete.inc:47
static scanTrace($message, $level)
static setComponentVersion($component_name)
static findComponentPath($name)
Locate the component path for the named component using the standard precedence rules.
static fireEventTo($event, $component, $parameter=null)
Fire an event to the specificed component.
static recordUpdate($component, $version_number, $description="", $fileName)
static getLatestVersion($component)
FakoliException is the base exception class for all Fakoli errors.
Definition: core.inc:53
Definition: menus.inc:41
Defines the Module class.
Definition: module.inc:57
Definition: page.inc:43
Section DataItem, defining the data model for sections within a site.
Definition: section.inc:45
SerializationManager handles import/export of DataItems via an XML file.
static getValue($component, $name)
Retrieve the value of the specified Setting.
Definition: settings.inc:104
executeSQLFile($sqlFile, $version_number)
recordUpdate($version, $description)
addMenuItem($item, $menu_identifier, $parent_identifier="", $title="", $section_name="", $sort_order=0)
reformatPhone(&$item, $field)
parseSQLStatements($lines)
executeVersionSql($version_number)
upgradeOneVersion($version_number, $function)
searchByIdentifier($identifier)
static upgradeComponentToVersion($component, $version)
addSectionContent($items, $section_name="/", $role="", $template="", $permissions="")
Utility function for use by calling classes to add an array of items of class Page,...
executeSQLStatements($sqlStatements)
upgrade($upgrade_to="")
executeVersionXML($version)
dependsOn($component, $version)
saveLogFile($version)
addModuleToPages($items, $module_name, $position='right', $sort_order=1)
Given an array of either identifiers that must be either CMS Page or ComponentPage identifiers or ite...
$xref_class
if(!checkRole($library->allow_access) &&! $library->allowAccess()) if(!checkRole($document->allow_access)) $d
Definition: download.inc:66
global $config
Definition: import.inc:4
$db
$pages
Definition: export.inc:38
$role
Definition: role_form.inc:41
$identifier
Definition: rss.inc:37
if(array_key_exists("HTTP_IF_MODIFIED_SINCE", $_SERVER)) $content
Definition: styles.css.inc:24