PageRenderTime 42ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/concrete/core/models/package.php

https://bitbucket.org/selfeky/xclusivescardwebsite
PHP | 726 lines | 584 code | 85 blank | 57 comment | 98 complexity | f5ff6839ad9593f88fffee324479d7af MD5 | raw file
  1. <?php
  2. defined('C5_EXECUTE') or die("Access Denied.");
  3. /**
  4. *
  5. * Groups and lists installed and available pages.
  6. * @package Utilities
  7. * @author Andrew Embler <andrew@concrete5.org>
  8. * @link http://www.concrete5.org
  9. * @license http://www.opensource.org/licenses/mit-license.php MIT
  10. *
  11. */
  12. class Concrete5_Model_PackageList extends Object {
  13. protected $packages = array();
  14. public function add($pkg) {
  15. $this->packages[] = $pkg;
  16. }
  17. public function getPackages() {
  18. return $this->packages;
  19. }
  20. public static function export($xml) {
  21. $packages = PackageList::get()->getPackages();
  22. $pkgs = $xml->addChild("packages");
  23. foreach($packages as $pkg) {
  24. $node = $pkgs->addChild('package');
  25. $node->addAttribute('handle', $pkg->getPackageHandle());
  26. }
  27. }
  28. public static function getHandle($pkgID) {
  29. if ($pkgID < 1) {
  30. return false;
  31. }
  32. $packageList = CacheLocal::getEntry('packageHandleList', false);
  33. if (is_array($packageList)) {
  34. return $packageList[$pkgID];
  35. }
  36. $packageList = array();
  37. $db = Loader::db();
  38. $r = $db->Execute('select pkgID, pkgHandle from Packages where pkgIsInstalled = 1');
  39. while ($row = $r->FetchRow()) {
  40. $packageList[$row['pkgID']] = $row['pkgHandle'];
  41. }
  42. CacheLocal::set('packageHandleList', false, $packageList);
  43. return $packageList[$pkgID];
  44. }
  45. public static function refreshCache() {
  46. CacheLocal::delete('packageHandleList', false);
  47. CacheLocal::delete('pkgList', 1);
  48. CacheLocal::delete('pkgList', 0);
  49. }
  50. public static function get($pkgIsInstalled = 1) {
  51. $pkgList = CacheLocal::getEntry('pkgList', $pkgIsInstalled);
  52. if ($pkgList != false) {
  53. return $pkgList;
  54. }
  55. $db = Loader::db();
  56. $r = $db->query("select pkgID, pkgName, pkgIsInstalled, pkgDescription, pkgVersion, pkgHandle, pkgDateInstalled from Packages where pkgIsInstalled = ? order by pkgID asc", array($pkgIsInstalled));
  57. $list = new PackageList();
  58. while ($row = $r->fetchRow()) {
  59. $pkg = new Package;
  60. $pkg->setPropertiesFromArray($row);
  61. $list->add($pkg);
  62. }
  63. CacheLocal::set('pkgList', $pkgIsInstalled, $list);
  64. return $list;
  65. }
  66. }
  67. /**
  68. *
  69. * Represents a package. A package is a grouping of Concrete functionality that can be "packaged" up and distributed
  70. * and easily installed in one spot.
  71. * @package Utilities
  72. * @author Andrew Embler <andrew@concrete5.org>
  73. * @link http://www.concrete5.org
  74. * @license http://www.opensource.org/licenses/mit-license.php MIT
  75. *
  76. */
  77. class Concrete5_Model_Package extends Object {
  78. protected $DIR_PACKAGES_CORE = DIR_PACKAGES_CORE;
  79. protected $DIR_PACKAGES = DIR_PACKAGES;
  80. protected $REL_DIR_PACKAGES_CORE = REL_DIR_PACKAGES_CORE;
  81. protected $REL_DIR_PACKAGES = REL_DIR_PACKAGES;
  82. public function getRelativePath() {
  83. $dirp = (is_dir($this->DIR_PACKAGES . '/' . $this->getPackageHandle())) ? $this->REL_DIR_PACKAGES : $this->REL_DIR_PACKAGES_CORE;
  84. return $dirp . '/' . $this->pkgHandle;
  85. }
  86. public function getPackageID() {return $this->pkgID;}
  87. public function getPackageName() {return t($this->pkgName);}
  88. public function getPackageDescription() {return t($this->pkgDescription);}
  89. public function getPackageHandle() {return $this->pkgHandle;}
  90. /**
  91. * Gets the date the package was added to the system,
  92. * if user is specified, returns in the current user's timezone
  93. * @param string $type (system || user)
  94. * @return string date formated like: 2009-01-01 00:00:00
  95. */
  96. function getPackageDateInstalled($type = 'system') {
  97. if(ENABLE_USER_TIMEZONES && $type == 'user') {
  98. $dh = Loader::helper('date');
  99. return $dh->getLocalDateTime($this->pkgDateInstalled);
  100. } else {
  101. return $this->pkgDateInstalled;
  102. }
  103. }
  104. public function getPackageVersion() {return $this->pkgVersion;}
  105. public function getPackageVersionUpdateAvailable() {return $this->pkgAvailableVersion;}
  106. public function isPackageInstalled() { return $this->pkgIsInstalled;}
  107. public function getChangelogContents() {
  108. if (file_exists($this->getPackagePath() . '/CHANGELOG')) {
  109. $contents = Loader::helper('file')->getContents($this->getPackagePath() . '/CHANGELOG');
  110. return nl2br(Loader::helper('text')->entities($contents));
  111. }
  112. return '';
  113. }
  114. /**
  115. * Returns the currently installed package version.
  116. * NOTE: This function only returns a value if getLocalUpgradeablePackages() has been called first!
  117. */
  118. public function getPackageCurrentlyInstalledVersion() {
  119. return $this->pkgCurrentVersion;
  120. }
  121. protected $appVersionRequired = '5.0.0';
  122. protected $pkgAllowsFullContentSwap = false;
  123. const E_PACKAGE_NOT_FOUND = 1;
  124. const E_PACKAGE_INSTALLED = 2;
  125. const E_PACKAGE_VERSION = 3;
  126. const E_PACKAGE_DOWNLOAD = 4;
  127. const E_PACKAGE_SAVE = 5;
  128. const E_PACKAGE_UNZIP = 6;
  129. const E_PACKAGE_INSTALL = 7;
  130. const E_PACKAGE_MIGRATE_BACKUP = 8;
  131. const E_PACKAGE_INVALID_APP_VERSION = 20;
  132. protected $errorText = array();
  133. public function getApplicationVersionRequired() {
  134. return $this->appVersionRequired;
  135. }
  136. public function hasInstallNotes() {
  137. return file_exists($this->getPackagePath() . '/' . DIRNAME_ELEMENTS . '/' . DIRNAME_DASHBOARD . '/install.php');
  138. }
  139. public function hasInstallPostScreen() {
  140. return file_exists($this->getPackagePath() . '/' . DIRNAME_ELEMENTS . '/' . DIRNAME_DASHBOARD . '/install_post.php');
  141. }
  142. public function allowsFullContentSwap() {
  143. return $this->pkgAllowsFullContentSwap;
  144. }
  145. public function showInstallOptionsScreen() {
  146. return $this->hasInstallNotes() || $this->allowsFullContentSwap();
  147. }
  148. public static function installDB($xmlFile) {
  149. if (!file_exists($xmlFile)) {
  150. return false;
  151. }
  152. // currently this is just done from xml
  153. $db = Loader::db();
  154. // this sucks - but adodb generates errors at the beginning because it attempts
  155. // to find a table that doesn't exist!
  156. $handler = $db->IgnoreErrors();
  157. if (Database::getDebug() == false) {
  158. ob_start();
  159. }
  160. $schema = Database::getADOSChema();
  161. $sql = $schema->ParseSchema($xmlFile);
  162. $db->IgnoreErrors($handler);
  163. if (!$sql) {
  164. $result->message = $db->ErrorMsg();
  165. return $result;
  166. }
  167. $r = $schema->ExecuteSchema();
  168. if (Database::getDebug() == false) {
  169. $dbLayerErrorMessage = ob_get_contents();
  170. ob_end_clean();
  171. }
  172. $result = new stdClass;
  173. $result->result = false;
  174. if ($dbLayerErrorMessage != '') {
  175. $result->message = $dbLayerErrorMessage;
  176. return $result;
  177. } if (!$r) {
  178. $result->message = $db->ErrorMsg();
  179. return $result;
  180. }
  181. $result->result = true;
  182. $db->CacheFlush();
  183. return $result;
  184. }
  185. /**
  186. * Loads package translation files into zend translate
  187. * @param string $locale
  188. * @param string $key
  189. * @return void
  190. */
  191. public function setupPackageLocalization($locale = NULL, $key = NULL) {
  192. $translate = Localization::getTranslate();
  193. if (is_object($translate)) {
  194. $path = $this->getPackagePath() . '/' . DIRNAME_LANGUAGES;
  195. if(!isset($locale) || !strlen($locale)) {
  196. $locale = ACTIVE_LOCALE;
  197. }
  198. if(!isset($key)) {
  199. $key = $locale;
  200. }
  201. if (file_exists($path . '/' . $locale . '/LC_MESSAGES/messages.mo')) {
  202. $translate->addTranslation($path . '/' . $locale . '/LC_MESSAGES/messages.mo', $key);
  203. }
  204. }
  205. }
  206. /**
  207. * Returns an array of package items (e.g. blocks, themes)
  208. */
  209. public function getPackageItems() {
  210. $items = array();
  211. Loader::model('single_page');
  212. Loader::library('mail/importer');
  213. Loader::model('job');
  214. Loader::model('collection_types');
  215. Loader::model('system/captcha/library');
  216. Loader::model('system/antispam/library');
  217. $items['attribute_categories'] = AttributeKeyCategory::getListByPackage($this);
  218. $items['permission_categories'] = PermissionKeyCategory::getListByPackage($this);
  219. $items['permission_access_entity_types'] = PermissionAccessEntityType::getListByPackage($this);
  220. $items['attribute_keys'] = AttributeKey::getListByPackage($this);
  221. $items['attribute_sets'] = AttributeSet::getListByPackage($this);
  222. $items['group_sets'] = GroupSet::getListByPackage($this);
  223. $items['page_types'] = CollectionType::getListByPackage($this);
  224. $items['mail_importers'] = MailImporter::getListByPackage($this);
  225. $items['configuration_values'] = Config::getListByPackage($this);
  226. $items['block_types'] = BlockTypeList::getByPackage($this);
  227. $items['page_themes'] = PageTheme::getListByPackage($this);
  228. $items['permissions'] = PermissionKey::getListByPackage($this);
  229. $items['single_pages'] = SinglePage::getListByPackage($this);
  230. $items['attribute_types'] = AttributeType::getListByPackage($this);
  231. $items['captcha_libraries'] = SystemCaptchaLibrary::getListByPackage($this);
  232. $items['antispam_libraries'] = SystemAntispamLibrary::getListByPackage($this);
  233. $items['jobs'] = Job::getListByPackage($this);
  234. $items['workflow_types'] = WorkflowType::getListByPackage($this);
  235. ksort($items);
  236. return $items;
  237. }
  238. public static function getItemName($item) {
  239. $txt = Loader::helper('text');
  240. Loader::model('single_page');
  241. if ($item instanceof BlockType) {
  242. return t($item->getBlockTypeName());
  243. } else if ($item instanceof PageTheme) {
  244. return $item->getThemeName();
  245. } else if ($item instanceof CollectionType) {
  246. return $item->getCollectionTypeName();
  247. } else if ($item instanceof MailImporter) {
  248. return $item->getMailImporterName();
  249. } else if ($item instanceof SinglePage) {
  250. return $item->getCollectionPath();
  251. } else if ($item instanceof AttributeType) {
  252. return tc('AttributeTypeName', $item->getAttributeTypeName());
  253. } else if ($item instanceof PermissionAccessEntityType) {
  254. return tc('PermissionAccessEntityTypeName', $item->getAccessEntityTypeName());
  255. } else if ($item instanceof PermissionKeyCategory) {
  256. return $txt->unhandle($item->getPermissionKeyCategoryHandle());
  257. } else if ($item instanceof AttributeKeyCategory) {
  258. return $txt->unhandle($item->getAttributeKeyCategoryHandle());
  259. } else if ($item instanceof AttributeSet) {
  260. $at = AttributeKeyCategory::getByID($item->getAttributeSetKeyCategoryID());
  261. return t('%s (%s)', tc('AttributeSetName', $item->getAttributeSetName()), $txt->unhandle($at->getAttributeKeyCategoryHandle()));
  262. } else if ($item instanceof GroupSet) {
  263. return $item->getGroupSetNAme();
  264. } else if (is_a($item, 'AttributeKey')) {
  265. $akc = AttributeKeyCategory::getByID($item->getAttributeKeyCategoryID());
  266. return t(' %s (%s)', $txt->unhandle($item->getAttributeKeyHandle()), $txt->unhandle($akc->getAttributeKeyCategoryHandle()));
  267. } else if ($item instanceof ConfigValue) {
  268. return ucwords(strtolower($txt->unhandle($item->key)));
  269. } else if ($item instanceof SystemAntispamLibrary) {
  270. return $item->getSystemAntispamLibraryName();
  271. } else if (is_a($item, 'PermissionKey')) {
  272. return tc('PermissionKeyName', $item->getPermissionKeyName());
  273. } else if (is_a($item, 'Job')) {
  274. return $item->getJobName();
  275. } else if (is_a($item, 'WorkflowType')) {
  276. return $item->getWorkflowTypeName();
  277. }
  278. }
  279. /**
  280. * Uninstalls the package. Removes any blocks, themes, or pages associated with the package.
  281. */
  282. public function uninstall() {
  283. $db = Loader::db();
  284. $items = $this->getPackageItems();
  285. foreach($items as $k => $array) {
  286. if (!is_array($array)) {
  287. continue;
  288. }
  289. foreach($array as $item) {
  290. if (is_a($item, 'Job')) {
  291. $item->uninstall();
  292. } else if (is_a($item, 'AttributeKey') || is_a($item, 'MailImporter')) {
  293. $item->delete();
  294. } else {
  295. switch(get_class($item)) {
  296. case 'BlockType':
  297. $item->delete();
  298. break;
  299. case 'PageTheme':
  300. $item->uninstall();
  301. break;
  302. case 'SinglePage':
  303. @$item->delete(); // we suppress errors because sometimes the wrapper pages can delete first.
  304. break;
  305. case 'SystemAntispamLibrary':
  306. $item->delete();
  307. break;
  308. case 'CollectionType':
  309. $item->delete();
  310. break;
  311. case 'MailImporter':
  312. $item->delete();
  313. break;
  314. case 'ConfigValue':
  315. $co = new Config();
  316. $co->setPackageObject($this);
  317. $co->clear($item->key);
  318. break;
  319. case 'AttributeKeyCategory':
  320. case 'PermissionKeyCategory':
  321. case 'AttributeSet':
  322. case 'GroupSet':
  323. case 'AttributeType':
  324. case 'WorkflowType':
  325. case 'PermissionKey':
  326. case 'PermissionAccessEntityType':
  327. $item->delete();
  328. break;
  329. default:
  330. if(method_exists($item, 'delete')) {
  331. $item->delete();
  332. } elseif(method_exists($item, 'uninstall')) {
  333. $item->uninstall();
  334. }
  335. break;
  336. }
  337. }
  338. }
  339. }
  340. $db->Execute("delete from Packages where pkgID = ?", array($this->pkgID));
  341. }
  342. protected function validateClearSiteContents($options) {
  343. $u = new User();
  344. if ($u->isSuperUser()) {
  345. // this can ONLY be used through the post. We will use the token to ensure that
  346. $valt = Loader::helper('validation/token');
  347. if ($valt->validate('install_options_selected', $options['ccm_token'])) {
  348. return true;
  349. }
  350. }
  351. return false;
  352. }
  353. public function swapContent($options) {
  354. if ($this->validateClearSiteContents($options)) {
  355. Loader::model("page_list");
  356. Loader::model("file_list");
  357. Loader::model("stack/list");
  358. $pl = new PageList();
  359. $pages = $pl->get();
  360. foreach($pages as $c) {
  361. $c->delete();
  362. }
  363. $fl = new FileList();
  364. $files = $fl->get();
  365. foreach($files as $f) {
  366. $f->delete();
  367. }
  368. // clear stacks
  369. $sl = new StackList();
  370. foreach($sl->get() as $c) {
  371. $c->delete();
  372. }
  373. $home = Page::getByID(HOME_CID);
  374. $blocks = $home->getBlocks();
  375. foreach($blocks as $b) {
  376. $b->deleteBlock();
  377. }
  378. $pageTypes = CollectionType::getList();
  379. foreach($pageTypes as $ct) {
  380. $ct->delete();
  381. }
  382. // now we add in any files that this package has
  383. if (is_dir($this->getPackagePath() . '/content_files')) {
  384. Loader::library('file/importer');
  385. $fh = new FileImporter();
  386. $contents = Loader::helper('file')->getDirectoryContents($this->getPackagePath() . '/content_files');
  387. foreach($contents as $filename) {
  388. $f = $fh->import($this->getPackagePath() . '/content_files/' . $filename, $filename);
  389. }
  390. }
  391. // now we parse the content.xml if it exists.
  392. Loader::library('content/importer');
  393. $ci = new ContentImporter();
  394. $ci->importContentFile($this->getPackagePath() . '/content.xml');
  395. }
  396. }
  397. public function testForInstall($package, $testForAlreadyInstalled = true) {
  398. // this is the pre-test routine that packages run through before they are installed. Any errors that come here
  399. // are to be returned in the form of an array so we can show the user. If it's all good we return true
  400. $db = Loader::db();
  401. $errors = array();
  402. $pkg = Loader::package($package);
  403. // Step 1 does that package exist ?
  404. if ((!is_dir(DIR_PACKAGES . '/' . $package) && (!is_dir(DIR_PACKAGES_CORE . '/' . $package))) || $package == '') {
  405. $errors[] = Package::E_PACKAGE_NOT_FOUND;
  406. } else if (!is_object($pkg)) {
  407. $errors[] = Package::E_PACKAGE_NOT_FOUND;
  408. }
  409. // Step 2 - check to see if the user has already installed a package w/this handle
  410. if ($testForAlreadyInstalled) {
  411. $cnt = $db->getOne("select count(*) from Packages where pkgHandle = ?", array($package));
  412. if ($cnt > 0) {
  413. $errors[] = Package::E_PACKAGE_INSTALLED;
  414. }
  415. }
  416. if (count($errors) == 0) {
  417. // test minimum application version requirement
  418. if (version_compare(APP_VERSION, $pkg->getApplicationVersionRequired(), '<')) {
  419. $errors[] = array(Package::E_PACKAGE_VERSION, $pkg->getApplicationVersionRequired());
  420. }
  421. }
  422. if (count($errors) > 0) {
  423. return $errors;
  424. } else {
  425. return true;
  426. }
  427. }
  428. public function mapError($testResults) {
  429. $errorText[Package::E_PACKAGE_INSTALLED] = t("You've already installed that package.");
  430. $errorText[Package::E_PACKAGE_NOT_FOUND] = t("Invalid Package.");
  431. $errorText[Package::E_PACKAGE_VERSION] = t("This package requires concrete5 version %s or greater.");
  432. $errorText[Package::E_PACKAGE_DOWNLOAD] = t("An error occurred while downloading the package.");
  433. $errorText[Package::E_PACKAGE_SAVE] = t("concrete5 was not able to save the package after download.");
  434. $errorText[Package::E_PACKAGE_UNZIP] = t('An error occurred while trying to unzip the package.');
  435. $errorText[Package::E_PACKAGE_INSTALL] = t('An error occurred while trying to install the package.');
  436. $errorText[Package::E_PACKAGE_MIGRATE_BACKUP] = t('Unable to backup old package directory to %s', DIR_FILES_TRASH);
  437. $errorText[Package::E_PACKAGE_INVALID_APP_VERSION] = t('This package isn\'t currently available for this version of concrete5. Please contact the maintainer of this package for assistance.');
  438. $testResultsText = array();
  439. foreach($testResults as $result) {
  440. if (is_array($result)) {
  441. $et = $errorText[$result[0]];
  442. array_shift($result);
  443. $testResultsText[] = vsprintf($et, $result);
  444. } else if (is_int($result)) {
  445. $testResultsText[] = $errorText[$result];
  446. } else if (!empty($result)) {
  447. $testResultsText[] = $result;
  448. }
  449. }
  450. return $testResultsText;
  451. }
  452. /*
  453. * Returns a path to where the packages files are located.
  454. * @access public
  455. * @return string $path
  456. */
  457. public function getPackagePath() {
  458. $dirp = (is_dir($this->DIR_PACKAGES . '/' . $this->getPackageHandle())) ? $this->DIR_PACKAGES : $this->DIR_PACKAGES_CORE;
  459. $path = $dirp . '/' . $this->getPackageHandle();
  460. return $path;
  461. }
  462. /**
  463. * returns a Package object for the given package id, null if not found
  464. * @param int $pkgID
  465. * @return Package
  466. */
  467. public function getByID($pkgID) {
  468. $db = Loader::db();
  469. $row = $db->GetRow("select * from Packages where pkgID = ?", array($pkgID));
  470. if ($row) {
  471. $pkg = Loader::package($row['pkgHandle']);
  472. if (is_object($pkg)) {
  473. $pkg->setPropertiesFromArray($row);
  474. return $pkg;
  475. }
  476. }
  477. }
  478. /**
  479. * returns a Package object for the given package handle, null if not found
  480. * @param string $pkgHandle
  481. * @return Package
  482. */
  483. public function getByHandle($pkgHandle) {
  484. $db = Loader::db();
  485. $row = $db->GetRow("select * from Packages where pkgHandle = ?", array($pkgHandle));
  486. if ($row) {
  487. $pkg = Loader::package($row['pkgHandle']);
  488. if (is_object($pkg)) {
  489. $pkg->setPropertiesFromArray($row);
  490. }
  491. return $pkg;
  492. }
  493. }
  494. /**
  495. * @return Package
  496. */
  497. public function install() {
  498. PackageList::refreshCache();
  499. $db = Loader::db();
  500. $dh = Loader::helper('date');
  501. $v = array($this->getPackageName(), $this->getPackageDescription(), $this->getPackageVersion(), $this->getPackageHandle(), 1, $dh->getSystemDateTime());
  502. $db->query("insert into Packages (pkgName, pkgDescription, pkgVersion, pkgHandle, pkgIsInstalled, pkgDateInstalled) values (?, ?, ?, ?, ?, ?)", $v);
  503. $pkg = Package::getByID($db->Insert_ID());
  504. Package::installDB($pkg->getPackagePath() . '/' . FILENAME_PACKAGE_DB);
  505. $env = Environment::get();
  506. $env->clearOverrideCache();
  507. return $pkg;
  508. }
  509. public function updateAvailableVersionNumber($vNum) {
  510. $db = Loader::db();
  511. $v = array($vNum, $this->getPackageID());
  512. $db->query("update Packages set pkgAvailableVersion = ? where pkgID = ?", $v);
  513. }
  514. public function upgradeCoreData() {
  515. $db = Loader::db();
  516. $p1 = Loader::package($this->getPackageHandle());
  517. $v = array($p1->getPackageName(), $p1->getPackageDescription(), $p1->getPackageVersion(), $this->getPackageID());
  518. $db->query("update Packages set pkgName = ?, pkgDescription = ?, pkgVersion = ? where pkgID = ?", $v);
  519. }
  520. public function upgrade() {
  521. Package::installDB($this->getPackagePath() . '/' . FILENAME_PACKAGE_DB);
  522. // now we refresh all blocks
  523. $items = $this->getPackageItems();
  524. if (is_array($items['block_types'])) {
  525. foreach($items['block_types'] as $item) {
  526. $item->refresh();
  527. }
  528. }
  529. }
  530. public static function getInstalledHandles() {
  531. $db = Loader::db();
  532. return $db->GetCol("select pkgHandle from Packages");
  533. }
  534. public static function getInstalledList() {
  535. $db = Loader::db();
  536. $r = $db->query("select * from Packages where pkgIsInstalled = 1 order by pkgDateInstalled asc");
  537. $pkgArray = array();
  538. while ($row = $r->fetchRow()) {
  539. $pkg = new Package;
  540. $pkg->setPropertiesFromArray($row);
  541. $pkgArray[] = $pkg;
  542. }
  543. return $pkgArray;
  544. }
  545. /**
  546. * Returns an array of packages that have newer versions in the local packages directory
  547. * than those which are in the Packages table. This means they're ready to be upgraded
  548. */
  549. public static function getLocalUpgradeablePackages() {
  550. $packages = Package::getAvailablePackages(false);
  551. $upgradeables = array();
  552. $db = Loader::db();
  553. foreach($packages as $p) {
  554. $row = $db->GetRow("select pkgID, pkgVersion from Packages where pkgHandle = ? and pkgIsInstalled = 1", array($p->getPackageHandle()));
  555. if ($row['pkgID'] > 0) {
  556. if (version_compare($p->getPackageVersion(), $row['pkgVersion'], '>')) {
  557. $p->pkgCurrentVersion = $row['pkgVersion'];
  558. $upgradeables[] = $p;
  559. }
  560. }
  561. }
  562. return $upgradeables;
  563. }
  564. public static function getRemotelyUpgradeablePackages() {
  565. $packages = Package::getInstalledList();
  566. $upgradeables = array();
  567. $db = Loader::db();
  568. foreach($packages as $p) {
  569. if (version_compare($p->getPackageVersion(), $p->getPackageVersionUpdateAvailable(), '<')) {
  570. $upgradeables[] = $p;
  571. }
  572. }
  573. return $upgradeables;
  574. }
  575. public function backup() {
  576. // you can only backup root level packages.
  577. // Need to figure something else out for core level
  578. if ($this->pkgHandle != '' && is_dir(DIR_PACKAGES . '/' . $this->pkgHandle)) {
  579. $ret = @rename(DIR_PACKAGES . '/' . $this->pkgHandle, DIR_FILES_TRASH . '/' . $this->pkgHandle . '_' . date('YmdHis'));
  580. if (!$ret) {
  581. return array(Package::E_PACKAGE_MIGRATE_BACKUP);
  582. }
  583. }
  584. }
  585. public function config($cfKey, $getFullObject = false) {
  586. $co = new Config();
  587. $co->setPackageObject($this);
  588. return $co->get($cfKey, $getFullObject);
  589. }
  590. public function saveConfig($cfKey, $value) {
  591. $co = new Config();
  592. $co->setPackageObject($this);
  593. return $co->save($cfKey, $value);
  594. }
  595. public function clearConfig($cfKey) {
  596. $co = new Config();
  597. $co->setPackageObject($this);
  598. return $co->clear($cfKey);
  599. }
  600. public static function getAvailablePackages($filterInstalled = true) {
  601. $dh = Loader::helper('file');
  602. $packages = $dh->getDirectoryContents(DIR_PACKAGES);
  603. if ($filterInstalled) {
  604. $handles = self::getInstalledHandles();
  605. // strip out packages we've already installed
  606. $packagesTemp = array();
  607. foreach($packages as $p) {
  608. if (!in_array($p, $handles)) {
  609. $packagesTemp[] = $p;
  610. }
  611. }
  612. $packages = $packagesTemp;
  613. }
  614. if (count($packages) > 0) {
  615. $packagesTemp = array();
  616. // get package objects from the file system
  617. foreach($packages as $p) {
  618. $pkg = Loader::package($p);
  619. if (!empty($pkg)) {
  620. $packagesTemp[] = $pkg;
  621. }
  622. }
  623. $packages = $packagesTemp;
  624. }
  625. return $packages;
  626. }
  627. }