1: <?php
  2: 
  3:   4:   5:   6:   7:   8:   9:  10:  11:  12:  13:  14:  15: 
 16: 
 17: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
 18: 
 19: cInclude('includes', 'functions.api.string.php');
 20: cInclude('includes', 'functions.con.php');
 21: 
 22:  23:  24:  25:  26:  27:  28:  29: 
 30: class cModuleSynchronizer extends cModuleHandler {
 31: 
 32:      33:  34:  35:  36: 
 37:     private $_lastIdMod = 0;
 38: 
 39:      40:  41:  42:  43:  44:  45:  46: 
 47:     private function _syncModule($dir, $oldModulName, $newModulName) {
 48:         global $client;
 49:         
 50:         if ($this->_isExistInTable($oldModulName, $client) == false) {
 51:             
 52:             $this->_addModule($newModulName);
 53:             cRegistry::appendLastOkMessage(sprintf(i18n('Module %s successfully synchronized'), $newModulName));
 54:         } else {
 55:             
 56:             if ($oldModulName != $newModulName) {
 57:                 $this->_updateModulnameInDb($oldModulName, $newModulName, $client);
 58:             }
 59:         }
 60:     }
 61: 
 62:      63:  64:  65:  66:  67:  68: 
 69:     private function _renameFiles($dir, $oldModulName, $newModulName) {
 70:         if (cFileHandler::exists($dir . $newModulName . '/' . $this->_directories['php'] . $oldModulName . '_input.php') == true) {
 71:             rename($dir . $newModulName . '/' . $this->_directories['php'] . $oldModulName . '_input.php', $dir . $newModulName . '/' . $this->_directories['php'] . $newModulName . '_input.php');
 72:         }
 73: 
 74:         if (cFileHandler::exists($dir . $newModulName . '/' . $this->_directories['php'] . $oldModulName . '_output.php') == true) {
 75:             rename($dir . $newModulName . '/' . $this->_directories['php'] . $oldModulName . '_output.php', $dir . $newModulName . '/' . $this->_directories['php'] . $newModulName . '_output.php');
 76:         }
 77: 
 78:         if (cFileHandler::exists($dir . $newModulName . '/' . $this->_directories['css'] . $oldModulName . '.css') == true) {
 79:             rename($dir . $newModulName . '/' . $this->_directories['css'] . $oldModulName . '.css', $dir . $newModulName . '/' . $this->_directories['css'] . $newModulName . '.css');
 80:         }
 81: 
 82:         if (cFileHandler::exists($dir . $newModulName . '/' . $this->_directories['js'] . $oldModulName . '.js') == true) {
 83:             rename($dir . $newModulName . '/' . $this->_directories['js'] . $oldModulName . '.js', $dir . $newModulName . '/' . $this->_directories['js'] . $newModulName . '.js');
 84:         }
 85:     }
 86: 
 87:      88:  89:  90:  91:  92:  93:  94:  95:  96:  97:  98:  99: 100: 
101:     private function _renameFileAndDir($dir, $dirNameOld, $dirNameNew, $client) {
102:         if (rename($dir . $dirNameOld, $dir . $dirNameNew) == FALSE) {
103:             return false;
104:         } else { 
105:             $this->_renameFiles($dir, $dirNameOld, $dirNameNew);
106:         }
107:         return true;
108:     }
109: 
110:     111: 112: 113: 114: 115: 116: 
117:     public function compareFileAndModuleTimestamp() {
118:         global $cfgClient;
119: 
120:         $synchLock = 0;
121: 
122:         $sql = sprintf('SELECT UNIX_TIMESTAMP(mod1.lastmodified) AS lastmodified,mod1.idclient,description,type, mod1.name, mod1.alias, mod1.idmod FROM %s AS mod1 WHERE mod1.idclient = %s', $this->_cfg['tab']['mod'], $this->_client);
123: 
124:         $db = cRegistry::getDb();
125:         $db->query($sql);
126:         $retIdMod = 0;
127: 
128:         while ($db->nextRecord()) {
129:             $showMessage = false;
130: 
131:             $modulePath = $cfgClient[$db->f('idclient')]['module']['path'] . $db->f('alias') . '/';
132:             $modulePHP = $modulePath . $this->_directories['php'] . $db->f('alias');
133: 
134:             $lastmodified = $db->f('lastmodified');
135: 
136:             $lastmodInput = $lastmodOutput = 0;
137: 
138:             if (cFileHandler::exists($modulePHP . '_input.php')) {
139:                 $lastmodInput = filemtime($modulePHP . '_input.php');
140:             }
141: 
142:             if (cFileHandler::exists($modulePHP . '_output.php')) {
143:                 $lastmodOutput = filemtime($modulePHP . '_output.php');
144:             }
145: 
146:             if (cFileHandler::exists($modulePath . "info.xml")) {
147:                 $lastModInfo = filemtime($modulePath . "info.xml");
148:                 if ($lastModInfo > $lastmodified) {
149:                     $modInfo = cXmlBase::xmlStringToArray(cFileHandler::read($modulePath . "info.xml"));
150:                     $mod = new cApiModule($db->f("idmod"));
151:                     if ($modInfo["description"] != $mod->get("description")) {
152:                         $mod->set("description", $modInfo["description"]);
153:                         $this->setLastModified($lastModInfo, $db->f('idmod'));
154:                     }
155:                     if ($modInfo["type"] != $mod->get("type")) {
156:                         $mod->set("type", $modInfo["type"]);
157:                         $this->setLastModified($lastModInfo, $db->f('idmod'));
158:                     }
159: 
160:                     if ($modInfo["name"] != $mod->get("name")) {
161:                         $mod->set("name", $modInfo["name"]);
162:                         $this->setLastModified($lastModInfo, $db->f('idmod'));
163:                     }
164: 
165:                     if ($modInfo["alias"] != $mod->get("alias")) {
166:                         $mod->set("alias", $modInfo["alias"]);
167:                         $this->setLastModified($lastModInfo, $db->f('idmod'));
168:                     }
169:                     $mod->store();
170:                     $synchLock = 1;
171:                     $showMessage = true;
172:                 }
173:             }
174: 
175:             $lastmodabsolute = max($lastmodInput, $lastmodOutput);
176:             if ($lastmodified < $lastmodabsolute) {
177:                 
178:                 $synchLock = 1;
179:                 $this->setLastModified($lastmodabsolute, $db->f('idmod'));
180:                 conGenerateCodeForAllartsUsingMod($db->f('idmod'));
181:                 $showMessage = true;
182:             }
183: 
184:             if (($idmod = $this->_synchronizeFilesystemAndDb($db)) != 0) {
185:                 $retIdMod = $idmod;
186:             }
187: 
188:             if ($showMessage) {
189:                 cRegistry::appendLastOkMessage(sprintf(i18n('Module %s successfully synchronized'), $db->f('name')));
190:             }
191:         }
192: 
193:         if ($synchLock == 0) {
194:             cRegistry::addInfoMessage(i18n('All modules are already synchronized'));
195:         }
196: 
197:         
198:         return $retIdMod;
199:     }
200: 
201:     202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 
212:     private function _synchronizeFilesystemAndDb($db) {
213:         $returnIdMod = 0;
214:         $this->initWithDatabaseRow($db);
215:         
216:         if ($this->modulePathExists() == false) {
217:             $modul = new cApiModule($db->f('idmod'));
218:             $returnIdMod = $db->f('idmod');
219:             if ($modul->moduleInUse($db->f('idmod')) == true) {
220:                 
221:                 if ($this->createModule() == false) {
222:                     $notification = new cGuiNotification();
223:                     $notification->displayNotification('error', i18n("Can not create module") . " " . $db->f('name'));
224:                 }
225:             } else {
226:                 
227:                 $sql = sprintf('DELETE  FROM %s WHERE idmod = %s AND idclient = %s', $this->_cfg['tab']['mod'], $db->f('idmod'), $this->_client);
228:                 $myDb = cRegistry::getDb();
229:                 $myDb->query($sql);
230:             }
231:         }
232:         return $returnIdMod;
233:     }
234: 
235:     236: 237: 238: 239: 240: 241: 242: 243: 
244:     public function synchronize() {
245:         global $cfgClient;
246: 
247:         
248:         $dir = $cfgClient[$this->_client]['module']['path'];
249: 
250:         if (is_dir($dir)) {
251:             if (false !== ($handle = cDirHandler::read($dir))) {
252:                 foreach ($handle as $file) {
253:                     if (false === cFileHandler::fileNameBeginsWithDot($file) && is_dir($dir . $file . '/')) {
254:                         $newFile = cString::cleanURLCharacters($file);
255:                         
256:                         if ($newFile == $file) {
257:                             $this->_syncModule($dir, $file, $newFile);
258:                         } else { 
259:                             if (is_dir($dir . $newFile)) { 
260:                                 
261:                                 
262:                                 $newDirName = $newFile . substr(md5(time() . rand(0, time())), 0, 4);
263: 
264:                                 
265:                                 if ($this->_renameFileAndDir($dir, $file, $newDirName, $this->_client) != false) {
266:                                     $this->_syncModule($dir, $file, $newDirName);
267:                                 }
268:                             } else { 
269:                                 
270:                                 if ($this->_renameFileAndDir($dir, $file, $newFile, $this->_client) != false) {
271:                                     $this->_syncModule($dir, $file, $newFile);
272:                                 }
273:                             }
274:                         }
275:                     }
276:                 }
277:             }
278:         }
279: 
280:         
281:         return $this->_lastIdMod;
282:     }
283: 
284:     285: 286: 287: 288: 289: 290: 291: 292: 293: 294: 295: 
296:     private function _isExistInTable($alias, $idclient) {
297:         $db = cRegistry::getDb();
298: 
299:         
300:         $sql = sprintf("SELECT * FROM %s WHERE alias='%s' AND idclient=%s", $this->_cfg['tab']['mod'], $alias, $idclient);
301: 
302:         $db->query($sql);
303: 
304:         
305:         if ($db->nextRecord()) {
306:             return true;
307:         } else {
308:             return false;
309:         }
310:     }
311: 
312:     313: 314: 315: 316: 317: 318: 319: 320: 321: 
322:     private function _updateModulnameInDb($oldName, $newName, $idclient) {
323:         $db = cRegistry::getDb();
324: 
325:         
326:         $sql = sprintf("SELECT * FROM %s WHERE alias='%s' AND idclient=%s", $this->_cfg['tab']['mod'], $oldName, $idclient);
327: 
328:         $db->query($sql);
329: 
330:         
331:         if ($db->nextRecord()) {
332:             $sqlUpdateName = sprintf("UPDATE %s SET alias='%s' WHERE idmod=%s", $this->_cfg['tab']['mod'], $newName, $db->f('idmod'));
333:             $db->query($sqlUpdateName);
334:             return;
335:         }
336:     }
337: 
338:     339: 340: 341: 342: 343: 
344:     private function _addModule($name) {
345: 
346:         
347:         $client = cRegistry::getClientId();
348:         $cfgClient = cRegistry::getClientConfig($client);
349: 
350:         
351:         $oModColl = new cApiModuleCollection();
352: 
353:         
354:         $modulePath = $cfgClient['module']['path'] . $name . '/';
355: 
356:         
357:         $modInfo = cXmlBase::xmlStringToArray(cFileHandler::read($modulePath . 'info.xml'));
358: 
359:         
360:         $mod = $oModColl->create($modInfo['name'], $client, $modInfo['alias'], $modInfo['type']);
361: 
362:         if (is_object($mod)) {
363:             
364:             $this->_lastIdMod = $mod->get('idmod');
365:         }
366:     }
367: 
368:     369: 370: 371: 372: 373: 374: 375: 
376:     public function setLastModified($timestamp, $idmod) {
377:         $oMod = new cApiModule((int) $idmod);
378:         if ($oMod->isLoaded()) {
379:             $oMod->set('lastmodified', date('Y-m-d H:i:s', $timestamp));
380:             $oMod->store();
381:         }
382:     }
383: 
384: }
385: