OXID eShop CE  4.9.6
 All Classes Files Functions Variables Pages
oxmodulelist.php
Go to the documentation of this file.
1 <?php
2 
9 class oxModuleList extends oxSuperCfg
10 {
11 
18  protected $_aModules = array();
19 
25  protected $_aModuleExtensions = null;
26 
32  protected $_aSkipFiles = array('functions.php', 'vendormetadata.php');
33 
39  public function getList()
40  {
41  return $this->_aModules;
42  }
43 
49  public function getModulesWithExtendedClass()
50  {
51  return $this->getConfig()->getModulesWithExtendedClass();
52  }
53 
59  public function getActiveModuleInfo()
60  {
61  $aModulePaths = $this->getModulePaths();
62 
63  // Extract module paths from extended classes
64  if (!is_array($aModulePaths) || count($aModulePaths) < 1) {
65  $aModulePaths = $this->extractModulePaths();
66  }
67 
68  $aDisabledModules = $this->getDisabledModules();
69  if (is_array($aDisabledModules) && count($aDisabledModules) > 0 && count($aModulePaths) > 0) {
70  $aModulePaths = array_diff_key($aModulePaths, array_flip($aDisabledModules));
71  }
72 
73  return $aModulePaths;
74  }
75 
81  public function getDisabledModuleInfo()
82  {
83  $aDisabledModules = $this->getDisabledModules();
84  $aModulePaths = array();
85 
86  if (is_array($aDisabledModules) && count($aDisabledModules) > 0) {
87  $aModulePaths = $this->getModulePaths();
88 
89  // Extract module paths from extended classes
90  if (!is_array($aModulePaths) || count($aModulePaths) < 1) {
91  $aModulePaths = $this->extractModulePaths();
92  }
93 
94  if (is_array($aModulePaths) || count($aModulePaths) > 0) {
95  $aModulePaths = array_intersect_key($aModulePaths, array_flip($aDisabledModules));
96  }
97  }
98 
99  return $aModulePaths;
100  }
101 
107  public function getModuleVersions()
108  {
109  return $this->getConfig()->getConfigParam('aModuleVersions');
110  }
111 
117  public function getModules()
118  {
119  return $this->getConfig()->getConfigParam('aModules');
120  }
121 
127  public function getDisabledModules()
128  {
129  return (array) $this->getConfig()->getConfigParam('aDisabledModules');
130  }
131 
137  public function getModulePaths()
138  {
139  return $this->getConfig()->getConfigParam('aModulePaths');
140  }
141 
147  public function getModuleEvents()
148  {
149  return (array) $this->getConfig()->getConfigParam('aModuleEvents');
150  }
151 
157  public function extractModulePaths()
158  {
159  $aModules = $this->getModulesWithExtendedClass();
160  $aModulePaths = array();
161 
162  if (is_array($aModules) && count($aModules) > 0) {
163  foreach ($aModules as $aModuleClasses) {
164  foreach ($aModuleClasses as $sModule) {
165  $sModuleId = substr($sModule, 0, strpos($sModule, "/"));
166  $aModulePaths[$sModuleId] = $sModuleId;
167  }
168  }
169  }
170 
171  return $aModulePaths;
172  }
173 
179  public function getModuleFiles()
180  {
181  return (array) $this->getConfig()->getConfigParam('aModuleFiles');
182  }
183 
189  public function getModuleTemplates()
190  {
191  return $this->getConfig()->getConfigParam('aModuleTemplates');
192  }
193 
202  public function getDisabledModuleClasses()
203  {
204  $aDisabledModules = $this->getDisabledModules();
205  $aModules = $this->getModulesWithExtendedClass();
206  $aModulePaths = $this->getModulePaths();
207 
208  $aDisabledModuleClasses = array();
209  if (isset($aDisabledModules) && is_array($aDisabledModules)) {
210  //get all disabled module paths
211  foreach ($aDisabledModules as $sId) {
212  $sPath = $aModulePaths[$sId];
213  if (!isset($sPath)) {
214  $sPath = $sId;
215  }
216  foreach ($aModules as $aModuleClasses) {
217  foreach ($aModuleClasses as $sModuleClass) {
218  if (strpos($sModuleClass, $sPath . "/") === 0) {
219  $aDisabledModuleClasses[] = $sModuleClass;
220  }
221  }
222  }
223  }
224  }
225 
226  return $aDisabledModuleClasses;
227  }
228 
232  public function cleanup()
233  {
234  $aDeletedModules = $this->getDeletedExtensions();
235 
236  //collecting deleted extension IDs
237  $aDeletedModuleIds = array_keys($aDeletedModules);
238 
239  // removing from aModules config array
240  $this->_removeExtensions($aDeletedModuleIds);
241 
242  // removing from aDisabledModules array
243  $this->_removeFromDisabledModulesArray($aDeletedModuleIds);
244 
245  // removing from aModulePaths array
246  $this->_removeFromModulesPathsArray($aDeletedModuleIds);
247 
248  // removing from aModuleEvents array
249  $this->_removeFromModulesEventsArray($aDeletedModuleIds);
250 
251  // removing from aModuleVersions array
252  $this->_removeFromModulesVersionsArray($aDeletedModuleIds);
253 
254  // removing from aModuleFiles array
255  $this->_removeFromModulesFilesArray($aDeletedModuleIds);
256 
257  // removing from aModuleTemplates array
258  $this->_removeFromModulesTemplatesArray($aDeletedModuleIds);
259 
260  //removing from config tables and templates blocks table
261  $this->_removeFromDatabase($aDeletedModuleIds);
262  }
263 
269  public function getDeletedExtensions()
270  {
271  $oModuleValidatorFactory = $this->getModuleValidatorFactory();
272  $oModuleMetadataValidator = $oModuleValidatorFactory->getModuleMetadataValidator();
273  $aModulesIds = $this->getModuleIds();
274  $oModule = $this->getModule();
275  $aDeletedExt = array();
276 
277  foreach ($aModulesIds as $sModuleId) {
278  $oModule->setModuleData(array('id' => $sModuleId));
279  if (!$oModuleMetadataValidator->validate($oModule)) {
280  $aDeletedExt[$sModuleId]['files'] = array($sModuleId . '/metadata.php');
281  } else {
282  $aInvalidExtensions = $this->_getInvalidExtensions($sModuleId);
283  if ($aInvalidExtensions) {
284  $aDeletedExt[$sModuleId]['extensions'] = $aInvalidExtensions;
285  }
286  }
287  }
288 
289  return $aDeletedExt;
290  }
291 
301  public function diffModuleArrays($aAllModuleArray, $aRemModuleArray)
302  {
303  if (is_array($aAllModuleArray) && is_array($aRemModuleArray)) {
304  foreach ($aAllModuleArray as $sClass => $aModuleChain) {
305  if (!is_array($aModuleChain)) {
306  $aModuleChain = array($aModuleChain);
307  }
308  if (isset($aRemModuleArray[$sClass])) {
309  if (!is_array($aRemModuleArray[$sClass])) {
310  $aRemModuleArray[$sClass] = array($aRemModuleArray[$sClass]);
311  }
312  $aAllModuleArray[$sClass] = array();
313  foreach ($aModuleChain as $sModule) {
314  if (!in_array($sModule, $aRemModuleArray[$sClass])) {
315  $aAllModuleArray[$sClass][] = $sModule;
316  }
317  }
318  if (!count($aAllModuleArray[$sClass])) {
319  unset ($aAllModuleArray[$sClass]);
320  }
321  } else {
322  $aAllModuleArray[$sClass] = $aModuleChain;
323  }
324  }
325  }
326 
327  return $aAllModuleArray;
328  }
329 
337  public function buildModuleChains($aModuleArray)
338  {
339  $aModules = array();
340  if (is_array($aModuleArray)) {
341  foreach ($aModuleArray as $sClass => $aModuleChain) {
342  $aModules[$sClass] = implode('&', $aModuleChain);
343  }
344  }
345 
346  return $aModules;
347  }
348 
354  public function getModule()
355  {
356  return oxNew('oxModule');
357  }
358 
364  protected function _removeExtensions($aModuleIds)
365  {
366  $aModuleExtensions = $this->getModulesWithExtendedClass();
367  $aExtensionsToDelete = array();
368  foreach ($aModuleIds as $sModuleId) {
369  $aExtensionsToDelete = array_merge_recursive($aExtensionsToDelete, $this->getModuleExtensions($sModuleId));
370  }
371 
372  $aUpdatedExtensions = $this->diffModuleArrays($aModuleExtensions, $aExtensionsToDelete);
373  $aUpdatedExtensionsChains = $this->buildModuleChains($aUpdatedExtensions);
374 
375  $this->getConfig()->saveShopConfVar('aarr', 'aModules', $aUpdatedExtensionsChains);
376  }
377 
383  protected function _removeFromDisabledModulesArray($aDeletedExtIds)
384  {
385  $oConfig = $this->getConfig();
386  $aDisabledExtensionIds = $this->getDisabledModules();
387  $aDisabledExtensionIds = array_diff($aDisabledExtensionIds, $aDeletedExtIds);
388  $oConfig->saveShopConfVar('arr', 'aDisabledModules', $aDisabledExtensionIds);
389  }
390 
396  protected function _removeFromModulesPathsArray($aDeletedModule)
397  {
398  $aModulePaths = $this->getModulePaths();
399 
400  foreach ($aDeletedModule as $sDeletedModuleId) {
401  if (isset($aModulePaths[$sDeletedModuleId])) {
402  unset($aModulePaths[$sDeletedModuleId]);
403  }
404  }
405 
406  $this->getConfig()->saveShopConfVar('aarr', 'aModulePaths', $aModulePaths);
407  }
408 
414  protected function _removeFromModulesVersionsArray($aDeletedModule)
415  {
416  $aModuleVersions = $this->getModuleVersions();
417 
418  foreach ($aDeletedModule as $sDeletedModuleId) {
419  if (isset($aModuleVersions[$sDeletedModuleId])) {
420  unset($aModuleVersions[$sDeletedModuleId]);
421  }
422  }
423 
424  $this->getConfig()->saveShopConfVar('aarr', 'aModuleVersions', $aModuleVersions);
425  }
426 
432  protected function _removeFromModulesEventsArray($aDeletedModule)
433  {
434  $aModuleEvents = $this->getModuleEvents();
435 
436  foreach ($aDeletedModule as $sDeletedModuleId) {
437  if (isset($aModuleEvents[$sDeletedModuleId])) {
438  unset($aModuleEvents[$sDeletedModuleId]);
439  }
440  }
441 
442  $this->getConfig()->saveShopConfVar('aarr', 'aModuleEvents', $aModuleEvents);
443  }
444 
450  protected function _removeFromModulesFilesArray($aDeletedModule)
451  {
452  $aModuleFiles = $this->getModuleFiles();
453 
454  foreach ($aDeletedModule as $sDeletedModuleId) {
455  if (isset($aModuleFiles[$sDeletedModuleId])) {
456  unset($aModuleFiles[$sDeletedModuleId]);
457  }
458  }
459 
460  $this->getConfig()->saveShopConfVar('aarr', 'aModuleFiles', $aModuleFiles);
461  }
462 
468  protected function _removeFromModulesTemplatesArray($aDeletedModule)
469  {
470  $aModuleTemplates = $this->getModuleTemplates();
471 
472  foreach ($aDeletedModule as $sDeletedModuleId) {
473  if (isset($aModuleTemplates[$sDeletedModuleId])) {
474  unset($aModuleTemplates[$sDeletedModuleId]);
475  }
476  }
477 
478  $this->getConfig()->saveShopConfVar('aarr', 'aModuleTemplates', $aModuleTemplates);
479  }
480 
488  protected function _removeFromDatabase($aDeletedExtIds)
489  {
490  if (!is_array($aDeletedExtIds) || !count($aDeletedExtIds)) {
491  return;
492  }
493 
494  $oDb = oxDb::getDb();
495 
496  $aConfigIds = $sDelExtIds = array();
497  foreach ($aDeletedExtIds as $sDeletedExtId) {
498  $aConfigIds[] = $oDb->quote('module:' . $sDeletedExtId);
499  $sDelExtIds[] = $oDb->quote($sDeletedExtId);
500  }
501 
502  $sConfigIds = implode(', ', $aConfigIds);
503  $sDelExtIds = implode(', ', $sDelExtIds);
504 
505  $aSql[] = "DELETE FROM oxconfig where oxmodule IN ($sConfigIds)";
506  $aSql[] = "DELETE FROM oxconfigdisplay where oxcfgmodule IN ($sConfigIds)";
507  $aSql[] = "DELETE FROM oxtplblocks where oxmodule IN ($sDelExtIds)";
508 
509  foreach ($aSql as $sQuery) {
510  $oDb->execute($sQuery);
511  }
512  }
513 
523  public function getModulesFromDir($sModulesDir, $sVendorDir = null)
524  {
525  $sModulesDir = oxRegistry::get('oxUtilsFile')->normalizeDir($sModulesDir);
526 
527  foreach (glob($sModulesDir . '*') as $sModuleDirPath) {
528 
529  $sModuleDirPath .= (is_dir($sModuleDirPath)) ? '/' : '';
530  $sModuleDirName = basename($sModuleDirPath);
531 
532  // skipping some file
533  if (in_array($sModuleDirName, $this->_aSkipFiles) || (!is_dir($sModuleDirPath) && substr($sModuleDirName, -4) != ".php")) {
534  continue;
535  }
536 
537  if ($this->_isVendorDir($sModuleDirPath)) {
538  // scanning modules vendor directory
539  $this->getModulesFromDir($sModuleDirPath, basename($sModuleDirPath));
540  } else {
541  // loading module info
542  $oModule = $this->getModule();
543  $sModuleDirName = (!empty($sVendorDir)) ? $sVendorDir . '/' . $sModuleDirName : $sModuleDirName;
544  if ($oModule->loadByDir($sModuleDirName)) {
545  $sModuleId = $oModule->getId();
546  $this->_aModules[$sModuleId] = $oModule;
547 
548  $aModulePaths = $this->getModulePaths();
549 
550  if (!is_array($aModulePaths) || !array_key_exists($sModuleId, $aModulePaths)) {
551  // saving module path info
552  $this->_saveModulePath($sModuleId, $sModuleDirName);
553 
554  //checking if this is new module and if it extends any eshop class
555  if (!$this->_extendsClasses($sModuleDirName)) {
556  // if not - marking it as disabled by default
557 
559  $oModuleCache = oxNew('oxModuleCache', $oModule);
561  $oModuleInstaller = oxNew('oxModuleInstaller', $oModuleCache);
562 
563  $oModuleInstaller->deactivate($oModule);
564  }
565  }
566  }
567  }
568  }
569  // sorting by name
570  if ($this->_aModules !== null) {
571  uasort($this->_aModules, array($this, '_sortModules'));
572  }
573 
574  return $this->_aModules;
575  }
576 
582  public function getModuleValidatorFactory()
583  {
584  return oxNew('oxModuleValidatorFactory');
585  }
586 
592  public function getModuleIds()
593  {
594  $aModuleIdsFromExtensions = $this->_getModuleIdsFromExtensions($this->getModulesWithExtendedClass());
595  $aModuleIdsFromFiles = array_keys($this->getModuleFiles());
596 
597  return array_unique(array_merge($aModuleIdsFromExtensions, $aModuleIdsFromFiles));
598  }
599 
607  public function getModuleExtensions($sModuleId)
608  {
609  if (!isset($this->_aModuleExtensions)) {
610  $aModuleExtension = $this->getConfig()->getModulesWithExtendedClass();
611  $oModule = $this->getModule();
612  $aExtension = array();
613  foreach ($aModuleExtension as $sOxClass => $aFiles) {
614  foreach ($aFiles as $sFilePath) {
615  $sId = $oModule->getIdByPath($sFilePath);
616  $aExtension[$sId][$sOxClass][] = $sFilePath;
617  }
618  }
619 
620  $this->_aModuleExtensions = $aExtension;
621  }
622 
623  return $this->_aModuleExtensions[$sModuleId] ? $this->_aModuleExtensions[$sModuleId] : array();
624  }
625 
634  protected function _sortModules($oModule1, $oModule2)
635  {
636  return strcasecmp($oModule1->getTitle(), $oModule2->getTitle());
637  }
638 
646  protected function _isVendorDir($sModuleDir)
647  {
648  if (is_dir($sModuleDir) && file_exists($sModuleDir . 'vendormetadata.php')) {
649  return true;
650  }
651 
652  return false;
653  }
654 
662  protected function _extendsClasses($sModuleDir)
663  {
664  $aModules = $this->getConfig()->getConfigParam('aModules');
665  if (is_array($aModules)) {
666  $sModules = implode('&', $aModules);
667 
668  if (preg_match("@(^|&+)" . $sModuleDir . "\b@", $sModules)) {
669  return true;
670  }
671  }
672 
673  return false;
674  }
675 
682  protected function _saveModulePath($sModuleId, $sModulePath)
683  {
684  $aModulePaths = $this->getModulePaths();
685 
686  $aModulePaths[$sModuleId] = $sModulePath;
687  $this->getConfig()->saveShopConfVar('aarr', 'aModulePaths', $aModulePaths);
688  }
689 
697  private function _getModuleIdsFromExtensions($aData)
698  {
699  $aModuleIds = array();
700  $oModule = $this->getModule();
701  foreach ($aData as $aModule) {
702  foreach ($aModule as $sFilePath) {
703  $sModuleId = $oModule->getIdByPath($sFilePath);
704  $aModuleIds[] = $sModuleId;
705  }
706  }
707 
708  return $aModuleIds;
709  }
710 
718  private function _getInvalidExtensions($sModuleId)
719  {
720  $aModules = $this->getModuleExtensions($sModuleId);
721  $aDeletedExt = array();
722 
723  foreach ($aModules as $sOxClass => $aModulesList) {
724  foreach ($aModulesList as $sModulePath) {
725  $sExtPath = $this->getConfig()->getModulesDir() . $sModulePath . '.php';
726  if (!file_exists($sExtPath)) {
727  $aDeletedExt[$sOxClass][] = $sModulePath;
728  }
729  }
730  }
731 
732  return $aDeletedExt;
733  }
734 }