1: <?php
2: /**
3: * This file contains abstract class for CONTENIDO plugins
4: *
5: * @package Plugin
6: * @subpackage PluginManager
7: * @version SVN Revision $Rev:$
8: *
9: * @author Frederic Schneider
10: * @copyright four for business AG <www.4fb.de>
11: * @license http://www.contenido.org/license/LIZENZ.txt
12: * @link http://www.4fb.de
13: * @link http://www.contenido.org
14: */
15:
16: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
17:
18: /**
19: * Standard class for Plugin Manager (PIM)
20: *
21: * @package Plugin
22: * @subpackage PluginManager
23: * @author frederic.schneider
24: */
25: class PimPluginSetup {
26:
27: // Initializing variables
28: // Variable for installation / update mode:
29: // Extracted or uploaded file?
30: public static $mode = 0;
31:
32: // File name of Xml configuration file for plugins
33: const PLUGIN_XML_FILENAME = "plugin.xml";
34:
35: // Specific sql prefix
36: const SQL_PREFIX = "!PREFIX!";
37:
38: // Class variable for cGuiPage
39: protected static $_GuiPage;
40:
41: // Class variable for PimPluginArchiveExtractor
42: protected static $_PimPluginArchiveExtractor;
43:
44: /**
45: * Help variable.
46: * If this variable is true PIM does not run uninstall and install
47: * sql file. Standard value: false (update sql file does not exist)
48: *
49: * @access private
50: * @var boolean
51: */
52: private static $_updateSqlFileExist = false;
53:
54: // Xml variables
55: // General informations of plugin
56: public static $XmlGeneral;
57:
58: // Plugin requirements
59: public static $XmlRequirements;
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: // GET and SET methods for installation routine
83: /**
84: * Set method for installation / update mode
85: * Mode 1: Plugin is already extracted
86: * Mode 2: Plugin is uploaded
87: *
88: * @access public
89: * @param string $mode
90: */
91: public static function setMode($mode) {
92: switch ($mode) {
93: case 'extracted':
94: self::$mode = 1;
95: break;
96: case 'uploaded':
97: self::$mode = 2;
98: break;
99: case 'uninstall':
100: self::$mode = 3;
101: break;
102: case 'update':
103: self::$mode = 4;
104: break;
105: }
106: }
107:
108: /**
109: * Set method for cGuiPage class
110: *
111: * @access public
112: * @param cGuiPage $page
113: */
114: public function setPageClass($page) {
115: return self::$_GuiPage = $page;
116: }
117:
118: /**
119: * Set method to change updateSqlFileExist variable
120: *
121: * @access protected
122: * @param boolean $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: * @access private
132: * @param string $tempArchiveNewPath Path to Zip archive
133: * @param string $tempArchiveName Name of Zip archive
134: * @return PimPluginArchiveExtractor
135: */
136: protected static function _setPimPluginArchiveExtractor($tempArchiveNewPath, $tempArchiveName) {
137: return self::$_PimPluginArchiveExtractor = new PimPluginArchiveExtractor($tempArchiveNewPath, $tempArchiveName);
138: }
139:
140: /**
141: * Set temporary xml content to static variables
142: *
143: * @access private
144: * @param string $xml
145: */
146: private function _setXml($xml) {
147:
148: // General plugin informations
149: self::$XmlGeneral = $xml->general;
150:
151: // Plugin requirements
152: self::$XmlRequirements = $xml->requirements;
153:
154: // CONTENIDO areas: *_area
155: self::$XmlArea = $xml->contenido->areas;
156:
157: // CONTENIDO actions: *_actions
158: self::$XmlActions = $xml->contenido->actions;
159:
160: // CONTENIDO frames: *_frame_files and *_files
161: self::$XmlFrames = $xml->contenido->frames;
162:
163: // CONTENIDO main navigations: *_nav_main
164: self::$XmlNavMain = $xml->contenido->nav_main;
165:
166: // CONTENIDO sub navigations: *_nav_sub
167: self::$XmlNavSub = $xml->contenido->nav_sub;
168:
169: // CONTENIDO Content Types: *_type
170: self::$XmlContentType = $xml->type;
171: }
172:
173: /**
174: * Set method for PluginId
175: *
176: * @access public
177: * @param integer $pluginId
178: * @return integer
179: */
180: public function setPluginId($pluginId = 0) {
181: return self::$_pluginId = $pluginId;
182: }
183:
184: /**
185: * Get method for installation / update mode
186: *
187: * @return integer
188: */
189: public static function getMode() {
190: return self::$mode;
191: }
192:
193: /**
194: * Get method for PluginId
195: *
196: * @access protected
197: * @return integer
198: */
199: protected static function _getPluginId() {
200: return self::$_pluginId;
201: }
202:
203: /**
204: * Set method for updateSqlFileExist variable
205: *
206: * @return boolean
207: */
208: protected function _getUpdateSqlFileExist() {
209: return self::$_updateSqlFileExist;
210: }
211:
212: // Help methods
213: /**
214: * checkXml
215: * Load plugin datas and run Xml checks
216: *
217: * @access public
218: */
219: public function checkXml() {
220: $cfg = cRegistry::getConfig();
221:
222: if (self::getMode() == 1) { // Plugin is already extracted
223: $XmlData = file_get_contents($cfg['path']['contenido'] . $cfg['path']['plugins'] . cSecurity::escapeString($_GET['pluginFoldername']) . DIRECTORY_SEPARATOR . self::PLUGIN_XML_FILENAME);
224: } elseif (self::getMode() == 2 || self::getMode() == 4) { // Plugin is
225: // uploaded /
226: // Update mode
227:
228: // Path to CONTENIDO temp dir
229: $tempArchiveNewPath = $cfg['path']['frontend'] . DIRECTORY_SEPARATOR . $cfg['path']['temp'];
230:
231: // Name of uploaded Zip archive
232: $tempArchiveName = cSecurity::escapeString($_FILES['package']['name']);
233:
234: // Initializing plugin archive extractor
235: try {
236: self::_setPimPluginArchiveExtractor($tempArchiveNewPath, $tempArchiveName);
237: } catch (cException $e) {
238: self::$_PimPluginArchiveExtractor->destroyTempFiles();
239: }
240:
241: // Check valid Zip archive
242: $this->checkZip();
243:
244: // Move temporary archive files into CONTENIDO temp dir
245: move_uploaded_file($_FILES['package']['tmp_name'], $tempArchiveNewPath . $tempArchiveName);
246:
247: // Get plugin.xml informations
248: $XmlData = self::$_PimPluginArchiveExtractor->extractArchiveFileToVariable(self::PLUGIN_XML_FILENAME);
249: }
250:
251: // Check and set plugin.xml
252: if ($this->validXml($XmlData) === true) {
253: $this->_setXml(simplexml_load_string($XmlData));
254: } else {
255: return self::error(i18n('Invalid Xml document. Please contact the plugin author.', 'pim'));
256: }
257: }
258:
259: /**
260: * Check file type, Plugin Manager accepts only Zip archives
261: *
262: * @access private
263: */
264: private function checkZip() {
265: if (substr($_FILES['package']['name'], -4) != ".zip") {
266: self::error(i18n('Plugin Manager accepts only Zip archives', 'pim'));
267: }
268: }
269:
270: /**
271: * Validate Xml source
272: *
273: * @access private
274: * @param string $xml
275: * @return boolean
276: */
277: private function validXml($xml) {
278: // Initializing PHP DomDocument class
279: $dom = new DomDocument();
280: $dom->loadXML($xml);
281:
282: // Validate
283: if ($dom->schemaValidate('plugins' . DIRECTORY_SEPARATOR . 'pim' . DIRECTORY_SEPARATOR . 'xml' . DIRECTORY_SEPARATOR . 'plugin_info.xsd')) {
284: return true;
285: } else {
286: return false;
287: }
288: }
289:
290: /**
291: * Error function with pim_error-Template
292: *
293: * @access protected
294: * @param string $message
295: */
296: protected static function error($message = '') {
297:
298: // Get session variable
299: $session = cRegistry::getSession();
300:
301: // Destroy temporary files if plugin is uploaded
302: if (self::getMode() == 2) {
303: self::$_PimPluginArchiveExtractor->destroyTempFiles();
304: }
305:
306: // Error template
307: $pimError = new cGuiPage('pim_error', 'pim');
308: $pimError->set('s', 'BACKLINK', $session->url('main.php?area=pim&frame=4'));
309: $pimError->set('s', 'LANG_BACKLINK', i18n('Back to Plugin Manager', 'pim'));
310: $pimError->displayError($message);
311: $pimError->render();
312: exit();
313: }
314:
315: /**
316: * Info function
317: *
318: * @access protected
319: * @param string $message
320: */
321: protected static function info($message = '') {
322: return self::$_GuiPage->displayInfo($message);
323: }
324:
325: }
326: ?>