Overview

Packages

  • CONTENIDO
  • Core
    • Authentication
    • Backend
    • Cache
    • CEC
    • Chain
    • ContentType
    • Database
    • Debug
    • Exception
    • Frontend
      • Search
      • URI
      • Util
    • GenericDB
      • Model
    • GUI
      • HTML
    • I18N
    • LayoutHandler
    • Log
    • Security
    • Session
    • Util
    • Validation
    • Versioning
    • XML
  • Module
    • ContentRssCreator
    • ContentSitemapHtml
    • ContentSitemapXml
    • ContentUserForum
    • NavigationTop
    • ScriptCookieDirective
  • mpAutoloaderClassMap
  • None
  • Plugin
    • ContentAllocation
    • CronjobOverview
    • FormAssistant
    • FrontendLogic
    • FrontendUsers
    • Linkchecker
    • ModRewrite
    • Newsletter
    • Repository
      • FrontendNavigation
      • KeywordDensity
    • SearchSolr
    • SmartyWrapper
    • UrlShortener
    • UserForum
    • Workflow
  • PluginManager
  • Setup
    • Form
    • GUI
    • Helper
      • Environment
      • Filesystem
      • MySQL
      • PHP
    • UpgradeJob

Classes

  • PimPlugin
  • PimPluginArchiveExtractor
  • PimPluginCollection
  • PimPluginRelations
  • PimPluginRelationsCollection
  • PimPluginSetup
  • PimPluginSetupInstall
  • PimPluginSetupStatus
  • PimPluginSetupUninstall
  • PimPluginSetupUpdate
  • PimPluginViewDependencies
  • PimPluginViewNavSub
  • Overview
  • Package
  • Class
  • Tree
  • Deprecated
  • Todo
  1: <?php
  2: /**
  3:  * This file contains abstract class for CONTENIDO plugins
  4:  *
  5:  * @package Plugin
  6:  * @subpackage PluginManager
  7:  * @author Frederic Schneider
  8:  * @copyright four for business AG <www.4fb.de>
  9:  * @license http://www.contenido.org/license/LIZENZ.txt
 10:  * @link http://www.4fb.de
 11:  * @link http://www.contenido.org
 12:  */
 13: 
 14: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
 15: 
 16: /**
 17:  * Standard class for Plugin Manager (PIM)
 18:  *
 19:  * @package Plugin
 20:  * @subpackage PluginManager
 21:  * @author frederic.schneider
 22:  */
 23: class PimPluginSetup {
 24: 
 25:     // Initializing variables
 26:     // Variable for installation / update mode:
 27:     // Extracted or uploaded file?
 28:     public static $mode = 0;
 29: 
 30:     // File name of Xml configuration file for plugins
 31:     const PLUGIN_XML_FILENAME = "plugin.xml";
 32: 
 33:     // Specific sql prefix
 34:     const SQL_PREFIX = "!PREFIX!";
 35: 
 36:     // Class variable for cGuiPage
 37:     protected static $_GuiPage;
 38: 
 39:     // Class variable for PimPluginArchiveExtractor
 40:     protected static $_PimPluginArchiveExtractor;
 41: 
 42:     /**
 43:      * Help variable.
 44:      * If this variable is true PIM does not run uninstall and install
 45:      * sql file. Standard value: false (update sql file does not exist)
 46:      *
 47:      * @var boolean
 48:      */
 49:     private static $_updateSqlFileExist = false;
 50: 
 51:     // Xml variables
 52:     // General informations of plugin
 53:     public static $XmlGeneral;
 54: 
 55:     // Plugin requirements
 56:     public static $XmlRequirements;
 57: 
 58:     // Plugin dependencies
 59:     public static $XmlDependencies;
 60: 
 61:     // CONTENIDO areas: *_area
 62:     public static $XmlArea;
 63: 
 64:     // CONTENIDO actions: *_actions
 65:     public static $XmlActions;
 66: 
 67:     // CONTENIDO frames: *_frame_files and *_files
 68:     public static $XmlFrames;
 69: 
 70:     // CONTENIDO main navigations: *_nav_main
 71:     public static $XmlNavMain;
 72: 
 73:     // CONTENIDO sub navigations: *_nav_sub
 74:     public static $XmlNavSub;
 75: 
 76:     // CONTENIDO content types: *_type
 77:     public static $XmlContentType;
 78: 
 79:     // Id of selected/new plugin
 80:     protected static $_pluginId = 0;
 81: 
 82:     // Name of selected plugin
 83:     protected static $_pluginName;
 84: 
 85:     // GET and SET methods for installation routine
 86:     /**
 87:      * Set method for installation / update mode
 88:      * Mode 1: Plugin is already extracted
 89:      * Mode 2: Plugin is uploaded
 90:      *
 91:      * @param string $mode
 92:      */
 93:     public static function setMode($mode) {
 94:         switch ($mode) {
 95:             case 'extracted':
 96:                 self::$mode = 1;
 97:                 break;
 98:             case 'uploaded':
 99:                 self::$mode = 2;
100:                 break;
101:             case 'uninstall':
102:                 self::$mode = 3;
103:                 break;
104:             case 'update':
105:                 self::$mode = 4;
106:                 break;
107:         }
108:     }
109: 
110:     /**
111:      * Set method for cGuiPage class
112:      *
113:      * @param cGuiPage $page
114:      */
115:     public function setPageClass($page) {
116:         return self::$_GuiPage = $page;
117:     }
118: 
119:     /**
120:      * Set method to change updateSqlFileExist variable
121:      *
122:      * @param bool $value
123:      */
124:     protected function _setUpdateSqlFileExist($value) {
125:         self::$_updateSqlFileExist = cSecurity::toBoolean($value);
126:     }
127: 
128:     /**
129:      * Initialzing and set variable for PimPluginArchiveExtractor class
130:      *
131:      * @param string $tempArchiveNewPath Path to Zip archive
132:      * @param string $tempArchiveName Name of Zip archive
133:      * @return PimPluginArchiveExtractor
134:      */
135:     protected static function _setPimPluginArchiveExtractor($tempArchiveNewPath, $tempArchiveName) {
136:         return self::$_PimPluginArchiveExtractor = new PimPluginArchiveExtractor($tempArchiveNewPath, $tempArchiveName);
137:     }
138: 
139:     /**
140:      * Set temporary xml content to static variables
141:      *
142:      * @param string $xml
143:      */
144:     private function _setXml($xml) {
145: 
146:         // General plugin informations
147:         self::$XmlGeneral = $xml->general;
148: 
149:         // Plugin requirements
150:         self::$XmlRequirements = $xml->requirements;
151: 
152:         // Plugin dependencies
153:         self::$XmlDependencies = $xml->dependencies;
154: 
155:         // CONTENIDO areas: *_area
156:         self::$XmlArea = $xml->contenido->areas;
157: 
158:         // CONTENIDO actions: *_actions
159:         self::$XmlActions = $xml->contenido->actions;
160: 
161:         // CONTENIDO frames: *_frame_files and *_files
162:         self::$XmlFrames = $xml->contenido->frames;
163: 
164:         // CONTENIDO main navigations: *_nav_main
165:         self::$XmlNavMain = $xml->contenido->nav_main;
166: 
167:         // CONTENIDO sub navigations: *_nav_sub
168:         self::$XmlNavSub = $xml->contenido->nav_sub;
169: 
170:         // CONTENIDO Content Types: *_type
171:         self::$XmlContentType = $xml->content_types;
172:     }
173: 
174:     /**
175:      * Set method for PluginId
176:      *
177:      * @param int $pluginId
178:      * @return int
179:      */
180:     public function setPluginId($pluginId = 0) {
181:         return self::$_pluginId = $pluginId;
182:     }
183: 
184:     /**
185:      * Set method for PluginName
186:      *
187:      * @param string $pluginName
188:      * @return string
189:      */
190:     public function setPluginName($pluginName = '') {
191:         return self::$_pluginName = $pluginName;
192:     }
193: 
194:     /**
195:      * Get method for installation / update mode
196:      *
197:      * @return int
198:      */
199:     public static function getMode() {
200:         return self::$mode;
201:     }
202: 
203:     /**
204:      * Get method for PluginId
205:      *
206:      * @return int
207:      */
208:     protected static function _getPluginId() {
209:         return self::$_pluginId;
210:     }
211: 
212:     /**
213:      * Get methos for PluginName
214:      *
215:      * @return string
216:      */
217:     protected static function _getPluginName() {
218:         return self::$_pluginName;
219:     }
220: 
221:     /**
222:      * Set method for updateSqlFileExist variable
223:      *
224:      * @return bool
225:      */
226:     protected function _getUpdateSqlFileExist() {
227:         return self::$_updateSqlFileExist;
228:     }
229: 
230:     // Help methods
231:     /**
232:      * checkXml
233:      * Load plugin datas and run Xml checks
234:      */
235:     public function checkXml() {
236:         $cfg = cRegistry::getConfig();
237: 
238:         if (self::getMode() == 1) { // Plugin is already extracted
239:             $XmlData = file_get_contents($cfg['path']['contenido'] . $cfg['path']['plugins'] . cSecurity::escapeString($_GET['pluginFoldername']) . DIRECTORY_SEPARATOR . self::PLUGIN_XML_FILENAME);
240:         } elseif (self::getMode() == 2 || self::getMode() == 4) { // Plugin is
241:                                                                   // uploaded /
242:                                                                   // Update mode
243: 
244:             // Path to CONTENIDO temp dir
245:             $tempArchiveNewPath = $cfg['path']['frontend'] . DIRECTORY_SEPARATOR . $cfg['path']['temp'];
246: 
247:             // Check if temp directory exists, otherwise try to create it
248:             if (!cDirHandler::exists($tempArchiveNewPath)) {
249:                 $success = cDirHandler::create($tempArchiveNewPath);
250: 
251:                 // If PIM can not create a temporary directory (if it does not exists), throw an error message
252:                 if (!$success) {
253:                     return self::error(sprintf(i18n('Plugin Manager can not found a temporary CONTENIDO directory. Also it is not possible to create a temporary directory at <em>%s</em>. You have to create it manualy.', 'pim'), $tempArchiveNewPath));              }
254:             }
255: 
256:             // Name of uploaded Zip archive
257:             $tempArchiveName = cSecurity::escapeString($_FILES['package']['name']);
258: 
259:             // Move temporary archive files into CONTENIDO temp dir
260:             move_uploaded_file($_FILES['package']['tmp_name'], $tempArchiveNewPath . $tempArchiveName);
261: 
262:             // Initializing plugin archive extractor
263:             try {
264:                 self::_setPimPluginArchiveExtractor($tempArchiveNewPath, $tempArchiveName);
265:             } catch (cException $e) {
266:                 self::$_PimPluginArchiveExtractor->destroyTempFiles();
267:             }
268: 
269:             // Check valid Zip archive
270:             $this->checkZip();
271: 
272:             // Get plugin.xml informations
273:             $XmlData = self::$_PimPluginArchiveExtractor->extractArchiveFileToVariable(self::PLUGIN_XML_FILENAME);
274:         }
275: 
276:         // Check and set plugin.xml
277:         if ($this->validXml($XmlData) === true) {
278:             $this->_setXml(simplexml_load_string($XmlData));
279:         } else {
280:             return self::error(i18n('Invalid Xml document. Please contact the plugin author.', 'pim'));
281:         }
282:     }
283: 
284:     /**
285:      * Check dependencies to other plugins (dependencies-Tag at plugin.xml)
286:      * Global function for uninstall and status mode
287:      * Install mode uses an own dependencies function
288:      *
289:      * @return boolean
290:      */
291:     public function checkDependencies() {
292: 
293:         // Initializings
294:         $cfg = cRegistry::getConfig();
295:         $pluginsDir = $cfg['path']['contenido'] . $cfg['path']['plugins'];
296: 
297:         // Get uuid from plugin to uninstall
298:         $this->_PimPluginCollection->setWhere('idplugin', self::_getPluginId());
299:         $this->_PimPluginCollection->query();
300:         $pimPluginSql = $this->_PimPluginCollection->next();
301:         $uuidUninstall = $pimPluginSql->get('uuid');
302: 
303:         // Reset query so we can use PimPluginCollection later again...
304:         $this->_PimPluginCollection->resetQuery();
305: 
306:         // Read all dirs
307:         $dirs = cDirHandler::read($pluginsDir);
308:         foreach ($dirs as $dirname) {
309: 
310:             // Skip plugin if it has no plugin.xml file
311:             if (!cFileHandler::exists($pluginsDir . $dirname . DIRECTORY_SEPARATOR . self::PLUGIN_XML_FILENAME)) {
312:                 continue;
313:             }
314: 
315:             // Read plugin.xml files from existing plugins at contenido/plugins dir
316:             $tempXmlContent = cFileHandler::read($pluginsDir . $dirname . DIRECTORY_SEPARATOR . self::PLUGIN_XML_FILENAME);
317: 
318:             // Write plugin.xml content into temporary variable
319:             $tempXml = simplexml_load_string($tempXmlContent);
320: 
321:             $dependenciesCount = count($tempXml->dependencies);
322:             for ($i = 0; $i < $dependenciesCount; $i++) {
323: 
324:                 // Security check
325:                 $depend = cSecurity::escapeString($tempXml->dependencies->depend[$i]);
326: 
327:                 // If is no dependencie name defined please go to next dependencie
328:                 if ($depend == "") {
329:                     continue;
330:                 }
331: 
332:                 // Build uuid variable from attributes
333:                 foreach ($tempXml->dependencies->depend[$i]->attributes() as $key => $value) {
334: 
335:                     // We use only uuid attribute and can ignore other attributes
336:                     if ($key  == "uuid") {
337:                         $uuidTemp = cSecurity::escapeString($value);
338:                     }
339:                 }
340: 
341:                 // Return false if uuid from plugin to uninstall and depended plugin is the same
342:                 // AND depended plugin is active
343:                 if ($uuidTemp === $uuidUninstall) {
344: 
345:                     $this->_PimPluginCollection->setWhere('uuid', $tempXml->general->uuid);
346:                     $this->_PimPluginCollection->setWhere('active', '1');
347:                     $this->_PimPluginCollection->query();
348:                     if ($this->_PimPluginCollection->count() != 0) {
349:                         self::setPluginName($tempXml->general->plugin_name);
350:                         return false;
351:                     }
352:                 }
353:             }
354:         }
355: 
356:         return true;
357:     }
358: 
359: 
360:     /**
361:      * Check file type, Plugin Manager accepts only Zip archives
362:      */
363:     private function checkZip() {
364:         if (substr($_FILES['package']['name'], -4) != ".zip") {
365:             self::error(i18n('Plugin Manager accepts only Zip archives', 'pim'));
366:         }
367:     }
368: 
369:     /**
370:      * Validate Xml source
371:      * @param string $xml
372:      * @return bool
373:      */
374:     private function validXml($xml) {
375:         // Initializing PHP DomDocument class
376:         $dom = new DomDocument();
377:         $dom->loadXML($xml);
378: 
379:         // Validate
380:         if ($dom->schemaValidate('plugins' . DIRECTORY_SEPARATOR . 'pim' . DIRECTORY_SEPARATOR . 'xml' . DIRECTORY_SEPARATOR . 'plugin_info.xsd')) {
381:             return true;
382:         } else {
383:             return false;
384:         }
385:     }
386: 
387:     /**
388:      * Error function with pim_error-Template
389:      * @param string $message
390:      */
391:     protected static function error($message = '') {
392: 
393:         // Get session variable
394:         $session = cRegistry::getSession();
395: 
396:         // Destroy temporary files if plugin is uploaded
397:         if (self::getMode() == 2) {
398:             self::$_PimPluginArchiveExtractor->destroyTempFiles();
399:         }
400: 
401:         // Error template
402:         $pimError = new cGuiPage('pim_error', 'pim');
403:         $pimError->set('s', 'BACKLINK', $session->url('main.php?area=pim&frame=4'));
404:         $pimError->set('s', 'LANG_BACKLINK', i18n('Back to Plugin Manager', 'pim'));
405:         $pimError->displayError($message);
406:         $pimError->render();
407:         exit();
408:     }
409: 
410:     /**
411:      * Info function, used displayOk CONTENIDO method
412:      * @param string $message
413:      */
414:     protected static function info($message = '') {
415:         return self::$_GuiPage->displayOk($message);
416:     }
417: 
418: }
419: 
420: ?>
CMS CONTENIDO 4.9.11 API documentation generated by ApiGen 2.8.0