1<?php 2/** 3 * Login system task for automated upgrade tasks. 4 * 5 * Copyright 2011-2017 Horde LLC (http://www.horde.org/) 6 * 7 * See the enclosed file COPYING for license information (LGPL). If you 8 * did not receive this file, see http://www.horde.org/licenses/lgpl21. 9 * 10 * @author Michael Slusarz <slusarz@horde.org> 11 * @category Horde 12 * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 13 * @package Core 14 */ 15abstract class Horde_Core_LoginTasks_SystemTask_Upgrade extends Horde_LoginTasks_SystemTask 16{ 17 /** 18 * The interval at which to run the task. 19 * 20 * @var integer 21 */ 22 public $interval = Horde_LoginTasks::EVERY; 23 24 /** 25 * The current application. 26 * 27 * @var string 28 */ 29 protected $_app = 'horde'; 30 31 /** 32 * Do these upgrade tasks require authentication? 33 * 34 * @var boolean 35 */ 36 protected $_auth = false; 37 38 /** 39 * The list of versions to upgrade. 40 * 41 * @var array 42 */ 43 protected $_toupgrade = array(); 44 45 /** 46 * The list of versions which upgrades will occur. 47 * 48 * @var array 49 */ 50 protected $_versions = array(); 51 52 /** 53 * Constructor. 54 */ 55 public function __construct() 56 { 57 usort($this->_versions, 'version_compare'); 58 59 if ($vers = $this->_pref('get')) { 60 foreach ($this->_versions as $val) { 61 /* Our versioning system is not compatible with PHP's 62 * version_compare, since x.0.foo is ALWAYS greater than 63 * x.0foo. */ 64 $compare = (substr_count($val, '.') != substr_count($vers, '.')) 65 ? preg_replace("/(\.0)((?:alpha|beta|RC)\d+)/i", "$2", $vers) 66 : $vers; 67 if (version_compare($compare, $val) === -1) { 68 $this->_toupgrade[] = $val; 69 } 70 } 71 } else { 72 $this->_toupgrade = $this->_versions; 73 } 74 75 $this->active = !empty($this->_toupgrade); 76 } 77 78 /** 79 * Perform upgrade tasks. 80 */ 81 public function execute() 82 { 83 foreach ($this->_toupgrade as $val) { 84 $this->_upgrade($val); 85 } 86 87 $this->_pref('set'); 88 } 89 90 /** 91 * Force re-run of all upgrade tasks. 92 */ 93 public function forceUpgrade() 94 { 95 $this->active = true; 96 $this->_toupgrade = $this->_versions; 97 $this->execute(); 98 } 99 100 /** 101 * Perform upgrade tasks for a given version. 102 * 103 * For those running a git checkout, the system task for a given version 104 * will run continuously until that version is released. Code should 105 * be added to not convert already converted values. 106 * 107 * @param string $version A version string. 108 */ 109 abstract protected function _upgrade($version); 110 111 /** 112 */ 113 public function skip() 114 { 115 /* Skip task until we are authenticated. */ 116 return ($this->_auth && 117 !$GLOBALS['registry']->isAuthenticated(array('app' => $this->_app))); 118 } 119 120 /** 121 * Manage the upgrade preferences. 122 * 123 * @param string $action Either 'get' or 'set'. 124 * 125 * @return string The current version. 126 */ 127 protected function _pref($action) 128 { 129 global $prefs, $registry; 130 131 $key = $this->_app; 132 if ($this->_auth) { 133 $key .= '_auth'; 134 } 135 136 $upgrade = @unserialize($prefs->getValue('upgrade_tasks')); 137 138 switch ($action) { 139 case 'get': 140 $val = isset($upgrade[$key]) 141 ? $upgrade[$key] 142 : null; 143 break; 144 145 case 'set': 146 $val = $registry->getVersion($this->_app, true); 147 $upgrade[$key] = $val; 148 $prefs->setValue('upgrade_tasks', serialize($upgrade)); 149 break; 150 } 151 152 return $val; 153 } 154 155} 156