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

  • cLayoutHandler
  • cLayoutSynchronizer
  • Overview
  • Package
  • Class
  • Tree
  • Deprecated
  • Todo
  1: <?php
  2: 
  3: /**
  4:  * This file contains the layout synchronizer class.
  5:  *
  6:  * @package Core
  7:  * @subpackage LayoutHandler
  8:  * @author Rusmir Jusufovic
  9:  * @copyright four for business AG <www.4fb.de>
 10:  * @license http://www.contenido.org/license/LIZENZ.txt
 11:  * @link http://www.4fb.de
 12:  * @link http://www.contenido.org
 13:  */
 14: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
 15: 
 16: /**
 17:  * This class synchronizes layouts from filesystem to database table.
 18:  *
 19:  * @package Core
 20:  * @subpackage LayoutHandler
 21:  */
 22: class cLayoutSynchronizer {
 23: 
 24:     /**
 25:      *
 26:      * @var array
 27:      */
 28:     protected $_cfg;
 29: 
 30:     /**
 31:      *
 32:      * @var array
 33:      */
 34:     protected $_cfgClient;
 35: 
 36:     /**
 37:      *
 38:      * @var int
 39:      */
 40:     protected $_lang;
 41: 
 42:     /**
 43:      *
 44:      * @var int
 45:      */
 46:     protected $_client;
 47: 
 48:     /**
 49:      *
 50:      * @var array
 51:      */
 52:     private $_outputMessage = array();
 53: 
 54:     /**
 55:      * Constructor to create an instance of this class.
 56:      *
 57:      * @param array $cfg
 58:      * @param array $cfgClient
 59:      * @param int $lang
 60:      * @param int $client
 61:      */
 62:     public function __construct($cfg, $cfgClient, $lang, $client) {
 63:         $this->_cfg = $cfg;
 64:         $this->_cfgClient = $cfgClient;
 65:         $this->_lang = $lang;
 66:         $this->_client = $client;
 67:     }
 68: 
 69:     /**
 70:      * Add a Layout to table or update a layout
 71:      *
 72:      * @param string $dir
 73:      * @param string $oldLayoutName
 74:      * @param string $newLayoutName
 75:      * @param string $idclient
 76:      *
 77:      * @throws cDbException
 78:      * @throws cException
 79:      * @throws cInvalidArgumentException
 80:      */
 81:     private function _addOrUpdateLayout($dir, $oldLayoutName, $newLayoutName, $idclient) {
 82:         // if layout dont exist in the $cfg["tab"]["lay"] table.
 83:         if ($this->_isExistInTable($oldLayoutName, $idclient) == false) {
 84:             // add new Layout in db-table
 85:             $layoutCollection = new cApiLayoutCollection();
 86:             $layoutCollection->create($newLayoutName, $idclient, $newLayoutName);
 87: 
 88:             // make a layout file if not exist
 89:             if (!cFileHandler::exists($dir . $newLayoutName . '/' . $newLayoutName . '.html')) {
 90:                 cFileHandler::write($dir . $newLayoutName . '/' . $newLayoutName . '.html', '');
 91:             }
 92: 
 93:             // set output message
 94:             $this->_outputMessage['info'][] = sprintf(i18n("Layout synchronization successful: %s"), $newLayoutName);
 95:         } else {
 96:             // update the name of the layout
 97:             if ($oldLayoutName != $newLayoutName) {
 98:                 $this->_updateModulnameInDb($oldLayoutName, $newLayoutName, $idclient);
 99:             }
100:         }
101:     }
102: 
103:     /**
104:      * Update the name of layout (if the name not allowes)
105:      *
106:      * @param string $oldName
107:      *         old name
108:      * @param string $newName
109:      *         new module name
110:      * @param int    $idclient
111:      *         id of client
112:      *
113:      * @throws cDbException
114:      * @throws cException
115:      */
116:     private function _updateModulnameInDb($oldName, $newName, $idclient) {
117:         $oLayColl = new cApiLayoutCollection();
118:         $oLayColl->select("alias='" . $oLayColl->escape($oldName) . "' AND idclient=" . (int) $idclient);
119:         if (false !== $oLay = $oLayColl->next()) {
120:             $oLay->set('alias', $newName);
121:             $oLay->store();
122:         }
123:     }
124: 
125:     /**
126:      * Rename the directory and files
127:      *
128:      * @param string $dir
129:      * @param string $dirNameOld
130:      * @param string $dirNameNew
131:      * @param int $client
132:      *         unused
133:      * @return bool
134:      */
135:     private function _renameFileAndDir($dir, $dirNameOld, $dirNameNew, $client) {
136:         if (rename($dir . $dirNameOld, $dir . $dirNameNew) == false) {
137:             return false;
138:         }
139: 
140:         $this->_renameFiles($dir, $dirNameOld, $dirNameNew);
141: 
142:         return true;
143:     }
144: 
145:     /**
146:      * Exist the layout in db-table
147:      *
148:      * @param string $alias
149:      *         layout name
150:      * @param int    $idclient
151:      *         client id
152:      * @return bool
153:      * @throws cDbException
154:      */
155:     private function _isExistInTable($alias, $idclient) {
156:         // Select depending from idclient all moduls wiht the name $name
157:         $oLayColl = new cApiLayoutCollection();
158:         $ids = $oLayColl->getIdsByWhereClause("alias='" . $oLayColl->escape($alias) . "' AND idclient=" . (int) $idclient);
159:         return (count($ids) > 0) ? true : false;
160:     }
161: 
162:     /**
163:      * Rename the Layout
164:      *
165:      * @param string $dir
166:      *         path to client layout-direcotry $dir
167:      * @param string $oldLayoutName
168:      *         layout name in file directory
169:      * @param string $newLayoutName
170:      *         clear layout name
171:      */
172:     private function _renameFiles($dir, $oldLayoutName, $newLayoutName) {
173:         if (cFileHandler::exists($dir . $newLayoutName . '/' . $oldLayoutName . '.html') == true) {
174:             rename($dir . $newLayoutName . '/' . $oldLayoutName . '.html', $dir . $newLayoutName . '/' . $newLayoutName . '.html');
175:         }
176:     }
177: 
178:     /**
179:      * Update the con_mod, the field lastmodified
180:      *
181:      * @param int $timestamp
182:      *         timestamp of last modification
183:      * @param int $idlay
184:      *         Id of layout
185:      * 
186:      * @throws cDbException
187:      * @throws cInvalidArgumentException
188:      */
189:     public function setLastModified($timestamp, $idlay) {
190:         $oLay = new cApiLayout((int) $idlay);
191:         if ($oLay->isLoaded()) {
192:             $oLay->set('lastmodified', date('Y-m-d H:i:s', $timestamp));
193:             $oLay->store();
194:         }
195:     }
196: 
197:     /**
198:      * Compare file change timestamp and the timestamp in ["tab"]["lay"].
199:      * If file had changed make new code :conGenerateCodeForAllArtsUsingMod
200:      *
201:      * @throws cDbException
202:      * @throws cInvalidArgumentException
203:      * @throws cException
204:      */
205:     private function _compareFileAndLayoutTimestamp() {
206:         // get all layouts from client
207:         $sql = sprintf("SELECT UNIX_TIMESTAMP(lastmodified) AS lastmodified, alias, name, description, idlay FROM %s WHERE idclient=%s", $this->_cfg['tab']['lay'], $this->_client);
208:         $notification = new cGuiNotification();
209:         $dir = $this->_cfgClient[$this->_client]['layout']['path'];
210: 
211:         $db = cRegistry::getDb();
212:         $db->query($sql);
213:         $retIdMod = 0;
214:         while ($db->nextRecord()) {
215:             $lastmodified = $db->f('lastmodified');
216: 
217:             // exist layout directory
218:             if (is_dir($dir . $db->f('alias') . '/')) {
219:                 if (cFileHandler::exists($dir . $db->f('alias') . '/' . $db->f('alias') . '.html')) {
220:                     $lastmodifiedLayout = filemtime($dir . $db->f('alias') . '/' . $db->f('alias') . '.html');
221: 
222:                     // update layout data
223:                     if ($lastmodified < $lastmodifiedLayout) {
224:                         // update field lastmodified in table lay
225:                         $this->setLastModified($lastmodifiedLayout, $db->f('idlay'));
226:                         $layout = new cLayoutHandler($db->f('idlay'), ' ', $this->_cfg, $this->_lang);
227:                         // Update CODE table
228:                         conGenerateCodeForAllartsUsingLayout($db->f('idlay'));
229:                         $this->_outputMessage['info'][] = i18n("Layout synchronization successful: ") . $db->f('name');
230:                     }
231:                 }
232:             } else {
233:                 $oLayout = new cApiLayout($db->f('idlay'));
234: 
235:                 $layout = new cLayoutHandler($db->f('idlay'), '', $this->_cfg, $this->_lang);
236:                 // is layout in use
237:                 if ($oLayout->isInUse()) {
238:                     // make layout file
239:                     $layout->saveLayout('');
240:                     $this->_outputMessage['info'][] = i18n("Layout synchronization successful, created: ") . $db->f('name');
241:                 } else {
242:                     // if not in use delete layout
243:                     if ($layout->eraseLayout()) {
244:                         layDeleteLayout($db->f('idlay'));
245:                         $this->_outputMessage['info'][] = i18n("Layout synchronization successful, deleted: ") . $db->f('name');
246:                     } else {
247:                         $this->_outputMessage['error'][] = i18n("Synchronization failed could not delete layout: ") . $db->f('name');
248:                     }
249:                 }
250:             }
251:         }
252:     }
253: 
254:     /**
255:      */
256:     private function _showOutputMessage() {
257:         $emptyMessage = true;
258:         $notification = new cGuiNotification();
259:         foreach ($this->_outputMessage as $typ) {
260:             foreach ($typ as $message) {
261:                 $emptyMessage = false;
262:                 // show display massage
263:                 $notification->displayNotification($typ, $message);
264:             }
265:         }
266:         if ($emptyMessage) {
267:             $notification->displayNotification('info', i18n("Synchronization successful!"));
268:         }
269:     }
270: 
271:     /**
272:      * Synchronize the Layout directory with the lay-table und the lay-table
273:      * with directory.
274:      *
275:      * @return bool
276:      * 
277:      * @throws cDbException
278:      * @throws cException
279:      * @throws cInvalidArgumentException
280:      */
281:     public function synchronize() {
282:         // update file and layout
283:         $this->_compareFileAndLayoutTimestamp();
284: 
285:         // get the path to clients layouts
286:         $dir = $this->_cfgClient[$this->_client]['layout']['path'];
287: 
288:         // is/exist directory
289:         if (!is_dir($dir)) {
290:             return false;
291:         }
292: 
293:         if (false !== ($handle = cDirHandler::read($dir))) {
294:             foreach ($handle as $file) {
295:                 // skip dirs to exclude
296:                 // @todo should use setting for dirs to exclude
297:                 if (cFileHandler::fileNameBeginsWithDot($file)) {
298:                     continue;
299:                 }
300: 
301:                 // skip entries that are no directories
302:                 if (false === is_dir($dir . $file . '/')) {
303:                     continue;
304:                 }
305: 
306:                 $newFile = cString::toLowerCase(cString::cleanURLCharacters($file));
307: 
308:                 if ($newFile == $file) {
309:                     // dir is ok
310:                     $this->_addOrUpdateLayout($dir, $file, $newFile, $this->_client);
311:                 } else {
312:                     // dir not ok (with not allowed characters)
313:                     if (is_dir($dir . $newFile) && cString::toLowerCase($file) != $newFile) {
314:                         // exist the new dir name after clean?
315:                         // make new dirname
316:                         $newDirName = $newFile . cString::getPartOfString(md5(time() . rand(0, time())), 0, 4);
317:                         // rename
318:                         if ($this->_renameFileAndDir($dir, $file, $newDirName, $this->_client) != false) {
319:                             $this->_addOrUpdateLayout($dir, $file, $newDirName, $this->_client);
320:                         }
321:                     } else {
322:                         // $newFile (dir) not exist
323:                         // rename dir old
324:                         if ($this->_renameFileAndDir($dir, $file, $newFile, $this->_client) != false) {
325:                             $this->_addOrUpdateLayout($dir, $file, $newFile, $this->_client);
326:                         }
327:                     }
328:                 }
329:             }
330:         }
331: 
332:         $this->_showOutputMessage();
333:     }
334: }
335: 
CMS CONTENIDO 4.10.0 API documentation generated by ApiGen 2.8.0