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
    • ContentSitemapHtml
    • ContentSitemapXml
    • ContentUserForum
    • NavigationTop
    • ScriptCookieDirective
  • mpAutoloaderClassMap
  • None
  • PHP
  • Plugin
    • ContentAllocation
    • CronjobOverview
    • FormAssistant
    • FrontendLogic
    • FrontendUsers
    • Linkchecker
    • ModRewrite
    • Newsletter
    • Repository
      • FrontendNavigation
      • KeywordDensity
    • 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: 
237:         $cfg = cRegistry::getConfig();
238: 
239:         if (self::getMode() == 1) { // Plugin is already extracted
240:             $XmlData = file_get_contents($cfg['path']['contenido'] . $cfg['path']['plugins'] . cSecurity::escapeString($_GET['pluginFoldername']) . DIRECTORY_SEPARATOR . self::PLUGIN_XML_FILENAME);
241:         } elseif (self::getMode() == 2 || self::getMode() == 4) { // Plugin is
242:                                                                   // uploaded /
243:                                                                   // Update mode
244: 
245:             // Path to CONTENIDO temp dir
246:             $tempArchiveNewPath = $cfg['path']['frontend'] . DIRECTORY_SEPARATOR . $cfg['path']['temp'];
247: 
248:             // Check if temp directory exists, otherwise try to create it
249:             if (!cDirHandler::exists($tempArchiveNewPath)) {
250:                 $success = cDirHandler::create($tempArchiveNewPath);
251: 
252:                 // If PIM can not create a temporary directory (if it does not exists), throw an error message
253:                 if (!$success) {
254:                     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));              }
255:             }
256: 
257:             // Name of uploaded Zip archive
258:             $tempArchiveName = cSecurity::escapeString($_FILES['package']['name']);
259: 
260:             // Move temporary archive files into CONTENIDO temp dir
261:             move_uploaded_file($_FILES['package']['tmp_name'], $tempArchiveNewPath . $tempArchiveName);
262: 
263:             // Initializing plugin archive extractor
264:             try {
265:                 self::_setPimPluginArchiveExtractor($tempArchiveNewPath, $tempArchiveName);
266:             } catch (cException $e) {
267:                 self::$_PimPluginArchiveExtractor->destroyTempFiles();
268:             }
269: 
270:             // Check valid Zip archive
271:             $this->checkZip();
272: 
273:             // Get plugin.xml informations
274:             $XmlData = self::$_PimPluginArchiveExtractor->extractArchiveFileToVariable(self::PLUGIN_XML_FILENAME);
275:         }
276: 
277:         // Check and set plugin.xml
278:         if ($this->validXml($XmlData) === true) {
279:             $this->_setXml(simplexml_load_string($XmlData));
280:         } else {
281:             return self::error(i18n('Invalid Xml document. Please contact the plugin author.', 'pim'));
282:         }
283:     }
284: 
285:     /**
286:      * Check dependencies to other plugins (dependencies-Tag at plugin.xml)
287:      * Global function for uninstall and status mode
288:      * Install mode uses an own dependencies function
289:      *
290:      * @return boolean
291:      */
292:     public function checkDependencies() {
293: 
294:         // Initializings
295:         $cfg = cRegistry::getConfig();
296:         $pluginsDir = $cfg['path']['contenido'] . $cfg['path']['plugins'];
297: 
298:         // Get uuid from plugin to uninstall
299:         $this->_PimPluginCollection->setWhere('idplugin', self::_getPluginId());
300:         $this->_PimPluginCollection->query();
301:         $pimPluginSql = $this->_PimPluginCollection->next();
302:         $uuidUninstall = $pimPluginSql->get('uuid');
303: 
304:         // Reset query so we can use PimPluginCollection later again...
305:         $this->_PimPluginCollection->resetQuery();
306: 
307:         // Read all dirs
308:         $dirs = cDirHandler::read($pluginsDir);
309:         foreach ($dirs as $dirname) {
310: 
311:             // Skip plugin if it has no plugin.xml file
312:             if (!cFileHandler::exists($pluginsDir . $dirname . DIRECTORY_SEPARATOR . self::PLUGIN_XML_FILENAME)) {
313:                 continue;
314:             }
315: 
316:             // Read plugin.xml files from existing plugins at contenido/plugins dir
317:             $tempXmlContent = cFileHandler::read($pluginsDir . $dirname . DIRECTORY_SEPARATOR . self::PLUGIN_XML_FILENAME);
318: 
319:             // Write plugin.xml content into temporary variable
320:             $tempXml = simplexml_load_string($tempXmlContent);
321: 
322:             $dependenciesCount = count($tempXml->dependencies);
323:             for ($i = 0; $i < $dependenciesCount; $i++) {
324: 
325:                 // Security check
326:                 $depend = cSecurity::escapeString($tempXml->dependencies->depend[$i]);
327: 
328:                 // If is no dependencie name defined please go to next dependencie
329:                 if ($depend == "") {
330:                     continue;
331:                 }
332: 
333:                 // Build uuid variable from attributes
334:                 foreach ($tempXml->dependencies->depend[$i]->attributes() as $key => $value) {
335: 
336:                     // We use only uuid attribute and can ignore other attributes
337:                     if ($key  == "uuid") {
338:                         $uuidTemp = cSecurity::escapeString($value);
339:                     }
340:                 }
341: 
342:                 // Return false if uuid from plugin to uninstall and depended plugin is the same
343:                 // AND depended plugin is active
344:                 if ($uuidTemp === $uuidUninstall) {
345: 
346:                     $this->_PimPluginCollection->setWhere('uuid', $tempXml->general->uuid);
347:                     $this->_PimPluginCollection->setWhere('active', '1');
348:                     $this->_PimPluginCollection->query();
349: 
350:                     if ($this->_PimPluginCollection->count() != 0) {
351:                         self::setPluginName($tempXml->general->plugin_name);
352:                         return false;
353:                     }
354:                 }
355:             }
356:         }
357: 
358:         return true;
359:     }
360: 
361: 
362:     /**
363:      * Check file type, Plugin Manager accepts only Zip archives
364:      */
365:     private function checkZip() {
366:         if (cString::getPartOfString($_FILES['package']['name'], -4) != ".zip") {
367:             self::error(i18n('Plugin Manager accepts only Zip archives', 'pim'));
368:         }
369:     }
370: 
371:     /**
372:      * Validate Xml source
373:      * @param string $xml
374:      * @return bool
375:      */
376:     private function validXml($xml) {
377: 
378:         // Initializing PHP DomDocument class
379:         $dom = new DomDocument();
380:         $dom->loadXML($xml);
381: 
382:         // Validate
383:         if ($dom->schemaValidate('plugins' . DIRECTORY_SEPARATOR . 'pim' . DIRECTORY_SEPARATOR . 'xml' . DIRECTORY_SEPARATOR . 'plugin_info.xsd')) {
384:             return true;
385:         } else {
386:             return false;
387:         }
388:     }
389: 
390:     /**
391:      * Error function with pim_error-Template
392:      * @param string $message
393:      */
394:     protected static function error($message = '') {
395: 
396:         // Get session variable
397:         $session = cRegistry::getSession();
398: 
399:         // Destroy temporary files if plugin is uploaded
400:         if (self::getMode() == 2) {
401:             self::$_PimPluginArchiveExtractor->destroyTempFiles();
402:         }
403: 
404:         // Error template
405:         $pimError = new cGuiPage('pim_error', 'pim');
406:         $pimError->set('s', 'BACKLINK', $session->url('main.php?area=pim&frame=4'));
407:         $pimError->set('s', 'LANG_BACKLINK', i18n('Back to Plugin Manager', 'pim'));
408:         $pimError->displayError($message);
409:         $pimError->render();
410:         exit();
411:     }
412: 
413:     /**
414:      * Info function, used displayOk CONTENIDO method
415:      * @param string $message
416:      */
417:     protected static function info($message = '') {
418:         return self::$_GuiPage->displayOk($message);
419:     }
420: 
421: }
422: 
423: ?>
CMS CONTENIDO 4.10.0 API documentation generated by ApiGen 2.8.0