PageRenderTime 49ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/concrete/core/models/page_theme.php

https://bitbucket.org/selfeky/xclusivescardwebsite
PHP | 673 lines | 463 code | 93 blank | 117 comment | 62 complexity | 8e8bfd0232d3f17dd602e89ad92cd4cc MD5 | raw file
  1. <?php
  2. defined('C5_EXECUTE') or die("Access Denied.");
  3. /**
  4. *
  5. * A page theme editable style object corresponds to a style in a stylesheet that is able to be manipulated through the dashboard.
  6. * @package Pages
  7. * @subpackage Themes
  8. */
  9. class Concrete5_Model_PageThemeEditableStyle extends Object {
  10. const TSTYPE_COLOR = 1;
  11. const TSTYPE_FONT = 10;
  12. const TSTYPE_CUSTOM = 20;
  13. public function getHandle() {return $this->ptsHandle;}
  14. public function getOriginalValue() {return $this->ptsOriginalValue;}
  15. public function getValue() {return $this->ptsValue;}
  16. public function getProperty() {
  17. // the original property that the stylesheet defines, like background-color, etc...
  18. return $this->ptsProperty;
  19. }
  20. public function getType() {return $this->ptsType;}
  21. public function getName() {
  22. $h = Loader::helper('text');
  23. return $h->unhandle($this->ptsHandle);
  24. }
  25. public function __construct($value = '') {
  26. if ($value) {
  27. $this->ptsValue = trim($value);
  28. $this->ptsOriginalValue = trim($value);
  29. $this->ptsProperty = substr($this->ptsValue, 0, strpos($this->ptsValue, ':'));
  30. $this->ptsValue = substr($this->ptsValue, strpos($this->ptsValue, ':') + 1);
  31. $this->ptsValue = trim(str_replace(';', '', $this->ptsValue));
  32. }
  33. }
  34. }
  35. /**
  36. * A class specifically for editable fonts
  37. */
  38. class Concrete5_Model_PageThemeEditableStyleFont extends Concrete5_Model_PageThemeEditableStyle {
  39. public function getFamily() {return $this->family;}
  40. public function getSize() {return $this->size;}
  41. public function getWeight() {return $this->weight;}
  42. public function getStyle() {return $this->style;}
  43. public function __construct($value) {
  44. parent::__construct($value);
  45. // value is pretty rigid. Has to be "font: normal normal 18px Book Antiqua"
  46. // so font: $weight $
  47. $expl = explode(' ', $this->ptsValue);
  48. $this->style = trim($expl[0]);
  49. $this->weight = trim($expl[1]);
  50. $this->size = preg_replace('/[^0-9]/', '', trim($expl[2]));
  51. $this->family = trim($expl[3]);
  52. if (count($expl) > 4) {
  53. for ($i = 4; $i < count($expl); $i++) {
  54. $this->family .= ' ' . trim($expl[$i]);
  55. }
  56. }
  57. }
  58. public function getShortValue() {
  59. return $this->style . '|' . $this->weight . '|' . $this->size . '|' . $this->family;
  60. }
  61. }
  62. /**
  63. *
  64. * When activating a theme, any file within the theme is loaded into the system as a Page Theme File. At that point
  65. * the file can then be used to create a new page type.
  66. * @package Pages
  67. * @subpackage Themes
  68. */
  69. class Concrete5_Model_PageThemeFile {
  70. protected $filename;
  71. protected $type;
  72. /**
  73. * Type of page corresponding to the view template (used by single pages in this theme). Typically that means this template file is "view.php"
  74. */
  75. const TFTYPE_VIEW = 1;
  76. /**
  77. * Type of page corresponding to the default page type. If a page type doesn't have a template in a particular theme, default is used.
  78. */
  79. const TFTYPE_DEFAULT = 2;
  80. /**
  81. * If this is used to designate what type of template this is, this means it corresponds to a single page like "login.php"
  82. */
  83. const TFTYPE_SINGLE_PAGE = 3;
  84. /**
  85. * This is a template for a new page type - one that hasn't been previously created in the system.
  86. */
  87. const TFTYPE_PAGE_TYPE_NEW = 4;
  88. /**
  89. * This is a template for a page type that already exists in the system.
  90. */
  91. const TFTYPE_PAGE_TYPE_EXISTING = 5;
  92. /**
  93. * Sets the filename of this object to the passed parameter.
  94. * @params string $filename
  95. * @return void
  96. */
  97. public function setFilename($filename) { $this->filename = $filename;}
  98. /**
  99. * Sets the type of file for this object to one of the constants.
  100. * @params string $type
  101. * @return void
  102. */
  103. public function setType($type) { $this->type = $type; }
  104. /**
  105. * Gets the filename for this theme file object.
  106. * @return string $filename
  107. */
  108. public function getFilename() { return $this->filename;}
  109. /**
  110. * Gets the type of file for this object.
  111. * @return string $type
  112. */
  113. public function getType() {return $this->type;}
  114. /**
  115. * Returns just the part of the filename prior to the extension
  116. * @return string $handle
  117. */
  118. public function getHandle() {
  119. return substr($this->filename, 0, strpos($this->filename, '.'));
  120. }
  121. }
  122. /**
  123. *
  124. * A page's theme is a pointer to a directory containing templates, CSS files and optionally PHP includes, images and JavaScript files.
  125. * Themes inherit down the tree when a page is added, but can also be set at the site-wide level (thereby overriding any previous choices.)
  126. * @package Pages and Collections
  127. * @subpackages Themes
  128. */
  129. class Concrete5_Model_PageTheme extends Object {
  130. protected $ptName;
  131. protected $ptID;
  132. protected $ptDescription;
  133. protected $ptDirectory;
  134. protected $ptThumbnail;
  135. protected $ptHandle;
  136. protected $ptURL;
  137. const E_THEME_INSTALLED = 1;
  138. const THEME_EXTENSION = ".php";
  139. const FILENAME_TYPOGRAPHY_CSS = "typography.css";
  140. const FILENAME_EXTENSION_CSS = "css";
  141. public static function getGlobalList() {
  142. return PageTheme::getList('pkgID > 0');
  143. }
  144. public static function getLocalList() {
  145. return PageTheme::getList('pkgID = 0');
  146. }
  147. public static function getListByPackage($pkg) {
  148. return PageTheme::getList('pkgID = ' . $pkg->getPackageID());
  149. }
  150. public static function getList($where = null) {
  151. if ($where != null) {
  152. $where = ' where ' . $where;
  153. }
  154. $db = Loader::db();
  155. $r = $db->query("select ptID from PageThemes" . $where);
  156. $themes = array();
  157. while ($row = $r->fetchRow()) {
  158. $pl = PageTheme::getByID($row['ptID']);
  159. $themes[] = $pl;
  160. }
  161. return $themes;
  162. }
  163. public static function getInstalledHandles() {
  164. $db = Loader::db();
  165. return $db->GetCol("select ptHandle from PageThemes");
  166. }
  167. public static function getAvailableThemes($filterInstalled = true) {
  168. // scans the directory for available themes. For those who don't want to go through
  169. // the hassle of uploading
  170. $db = Loader::db();
  171. $dh = Loader::helper('file');
  172. $themes = $dh->getDirectoryContents(DIR_FILES_THEMES);
  173. if ($filterInstalled) {
  174. // strip out themes we've already installed
  175. $handles = $db->GetCol("select ptHandle from PageThemes");
  176. $themesTemp = array();
  177. foreach($themes as $t) {
  178. if (!in_array($t, $handles)) {
  179. $themesTemp[] = $t;
  180. }
  181. }
  182. $themes = $themesTemp;
  183. }
  184. if (count($themes) > 0) {
  185. $themesTemp = array();
  186. // get theme objects from the file system
  187. foreach($themes as $t) {
  188. $th = PageTheme::getByFileHandle($t);
  189. if (!empty($th)) {
  190. $themesTemp[] = $th;
  191. }
  192. }
  193. $themes = $themesTemp;
  194. }
  195. return $themes;
  196. }
  197. public static function getByFileHandle($handle, $dir = DIR_FILES_THEMES) {
  198. $dirt = $dir . '/' . $handle;
  199. if (is_dir($dirt)) {
  200. $res = PageTheme::getThemeNameAndDescription($dirt);
  201. $th = new PageTheme;
  202. $th->ptHandle = $handle;
  203. $th->ptDirectory = $dirt;
  204. $th->ptName = $res->ptName;
  205. $th->ptDescription = $res->ptDescription;
  206. switch($dir) {
  207. case DIR_FILES_THEMES:
  208. $th->ptURL = BASE_URL . DIR_REL . '/' . DIRNAME_THEMES . '/' . $handle;
  209. break;
  210. }
  211. return $th;
  212. }
  213. }
  214. /**
  215. * Looks into the current theme and outputs the contents of the stylesheet.
  216. * This function will eventually check to see if a cached version is available, as well as tie the dynamic areas of the stylesheet to whatever they have been saved.
  217. * @param string $file
  218. */
  219. public function outputStyleSheet($file, $styles = false) {
  220. print $this->parseStyleSheet($file, $styles);
  221. }
  222. public function parseStyleSheet($file, $styles = false) {
  223. $env = Environment::get();
  224. $themeRec = $env->getUncachedRecord(DIRNAME_THEMES . '/' . $this->getThemeHandle() . '/' . $file, $this->getPackageHandle());
  225. if ($themeRec->exists()) {
  226. $fh = Loader::helper('file');
  227. $contents = $fh->getContents($themeRec->file);
  228. // replace all url( instances with url starting with path to theme
  229. $contents = preg_replace('/(url\(\')([^\)]*)/', '$1' . $this->getThemeURL() . '/$2', $contents);
  230. $contents = preg_replace('/(url\(")([^\)]*)/', '$1' . $this->getThemeURL() . '/$2', $contents);
  231. $contents = preg_replace('/(url\((?![\'"]))([^\)]*)/', '$1' . $this->getThemeURL() . '/$2', $contents);
  232. $contents = str_replace('url(' . $this->getThemeURL() . '/data:image', 'url(data:image', $contents);
  233. // load up all tokens from the db for this stylesheet.
  234. // if a replacement style array is passed then we use that instead of the database (as is the case when previewing)
  235. if (!is_array($styles)) {
  236. $db = Loader::db();
  237. $ptes = $db->GetAll("select ptsHandle, ptsValue, ptsType from PageThemeStyles where ptID = ?", $this->getThemeID());
  238. $styles = array();
  239. foreach($ptes as $p) {
  240. $pts = new PageThemeEditableStyle($p['ptsValue']);
  241. $pts->setPropertiesFromArray($p);
  242. $styles[] = $pts;
  243. }
  244. }
  245. $replacements = array();
  246. $searches = array();
  247. foreach($styles as $p) {
  248. if ($p->getType() == PageThemeEditableStyle::TSTYPE_CUSTOM) {
  249. $contents = preg_replace("/\/\*[\s]?customize_" . $p->getHandle() . "[\s]?\*\/(.*)\/\*[\s]?customize_" . $p->getHandle() . "[\s]?\*\//i",
  250. "/* customize_" . $p->getHandle() . " */ " . $p->getValue() . " /* customize_" . $p->getHandle() . " */"
  251. , $contents);
  252. } else {
  253. $contents = preg_replace("/\/\*[\s]?customize_" . $p->getHandle() . "[\s]?\*\/[\s]?" . $p->getProperty() . "(.*)\/\*[\s]?customize_" . $p->getHandle() . "[\s]?\*\//i",
  254. "/* customize_" . $p->getHandle() . " */ " . $p->getValue() . " /* customize_" . $p->getHandle() . " */"
  255. , $contents);
  256. }
  257. }
  258. return $contents;
  259. }
  260. }
  261. public function mergeStylesFromPost($post) {
  262. $values = array();
  263. $styles = $this->getEditableStylesList();
  264. foreach($styles as $sto) {
  265. foreach($sto as $st) {
  266. $ptes = new PageThemeEditableStyle();
  267. $ptes->ptsHandle = $st->getHandle();
  268. $ptes->ptsType = $st->getType();
  269. $ptes->ptsProperty = $st->getProperty();
  270. switch($st->getType()) {
  271. case PageThemeEditableStyle::TSTYPE_COLOR:
  272. if (isset($post['input_theme_style_' . $st->getHandle() . '_' . $st->getType()])) {
  273. $ptes->ptsValue = $ptes->getProperty() . ':' . $post['input_theme_style_' . $st->getHandle() . '_' . $st->getType()] . ';';
  274. $values[] = $ptes;
  275. }
  276. break;
  277. case PageThemeEditableStyle::TSTYPE_CUSTOM:
  278. if (isset($post['input_theme_style_' . $st->getHandle() . '_' . $st->getType()])) {
  279. $ptes->ptsValue = $post['input_theme_style_' . $st->getHandle() . '_' . $st->getType()];
  280. $values[] = $ptes;
  281. }
  282. break;
  283. case PageThemeEditableStyle::TSTYPE_FONT:
  284. if (isset($post['input_theme_style_' . $st->getHandle() . '_' . $st->getType()])) {
  285. $value = $post['input_theme_style_' . $st->getHandle() . '_' . $st->getType()];
  286. // now we transform it from it's post, which has pipes and separators and crap
  287. $fv = explode('|', $value);
  288. $ptes->ptsValue = $ptes->getProperty() . ':' . $fv[0] . ' ' . $fv[1] . ' ' . $fv[2] . 'px ' . $fv[3] . ';';
  289. $values[] = $ptes;
  290. }
  291. break;
  292. }
  293. }
  294. }
  295. return $values;
  296. }
  297. /**
  298. * Removes any custom styles by clearing them out of the database
  299. * @return void
  300. */
  301. public function reset() {
  302. $db = Loader::db();
  303. $db->Execute('delete from PageThemeStyles where ptID = ?', array($this->ptID));
  304. // now we reset all cached css files in this theme
  305. $sheets = $this->getStyleSheets();
  306. foreach($sheets as $s) {
  307. if (file_exists(DIR_FILES_CACHE . '/' . DIRNAME_CSS . '/' . $this->getThemeHandle() . '/' . $s)) {
  308. unlink(DIR_FILES_CACHE . '/' . DIRNAME_CSS . '/' . $this->getThemeHandle() . '/' . $s);
  309. }
  310. }
  311. }
  312. /**
  313. * Takes an associative array of pagethemeeditablestyle objects and saves it to the PageThemeStyles table
  314. * @param array $styles
  315. */
  316. public function saveEditableStyles($styles) {
  317. $db = Loader::db();
  318. foreach($styles as $ptes) {
  319. $db->Replace('PageThemeStyles', array(
  320. 'ptID' => $this->getThemeID(),
  321. 'ptsHandle' => $ptes->getHandle(),
  322. 'ptsValue' => $ptes->getValue(),
  323. 'ptsType' => $ptes->getType()
  324. ),
  325. array('ptID', 'ptsHandle', 'ptsType'), true);
  326. }
  327. // now we reset all cached css files in this theme
  328. $sheets = $this->getStyleSheets();
  329. foreach($sheets as $s) {
  330. if (file_exists(DIR_FILES_CACHE . '/' . DIRNAME_CSS . '/' . $this->getThemeHandle() . '/' . $s)) {
  331. unlink(DIR_FILES_CACHE . '/' . DIRNAME_CSS . '/' . $this->getThemeHandle() . '/' . $s);
  332. }
  333. }
  334. }
  335. private function getStyleSheets() {
  336. $fh = Loader::helper('file');
  337. $files = $fh->getDirectoryContents($this->getThemeDirectory());
  338. $sheets = array();
  339. foreach($files as $f) {
  340. $pos = strrpos($f, '.');
  341. $ext = substr($f, $pos + 1);
  342. if ($ext == PageTheme::FILENAME_EXTENSION_CSS) {
  343. $sheets[] = $f;
  344. }
  345. }
  346. return $sheets;
  347. }
  348. /**
  349. * Parses the style declaration found in the stylesheet to return the type of editable style
  350. */
  351. private function getEditableStyleType($value) {
  352. // thx yamanoi
  353. if (preg_match('/^\s*font\s*:/',$value)) {
  354. return PageThemeEditableStyle::TSTYPE_FONT;
  355. }
  356. if (preg_match('/^\s*([a-z]+-)*color\s*:/',$value)) {
  357. return PageThemeEditableStyle::TSTYPE_COLOR;
  358. }
  359. return PageThemeEditableStyle::TSTYPE_CUSTOM;
  360. }
  361. /**
  362. * Retrieves an array of editable style objects from the current them. This is accomplished by locating all style sheets in the root of the theme, parsing all their contents
  363. * @param string $file
  364. * @return array
  365. */
  366. public function getEditableStylesList() {
  367. $sheets = $this->getStyleSheets();
  368. $styles = array();
  369. foreach($sheets as $file) {
  370. $ss = $this->parseStyleSheet($file);
  371. // match all tokens
  372. $matches = array();
  373. //REGEX NEW LINE BUG!
  374. //currently this doesn't capture customize_ tags that span multiple lines
  375. //you can easily make the .* dot character match multiple lines by adding the "s" modifiers to the end of the expression...
  376. //but this introduces another bug where you can't have two tags with the same name within a style sheet
  377. //Any regex wizards out there wanting to give it a shot?
  378. preg_match_all("/\/\*[\s]?customize_(.*)[\s]?\*\/(.*)\/\*[\s]?customize_\\1[\s]?\*\//isU", $ss, $matches);
  379. // the format of the $matches array is [1] = the handle of the editable style object, [2] = the value (which we need to trim)
  380. // handles are unique.
  381. $handles = $matches[1];
  382. $values = $matches[2];
  383. for($i = 0 ; $i < count($handles); $i++) {
  384. $type = $this->getEditableStyleType($values[$i]);
  385. if ($type == PageThemeEditableStyle::TSTYPE_FONT) {
  386. $pte = new PageThemeEditableStyleFont(trim($values[$i]));
  387. } else {
  388. $pte = new PageThemeEditableStyle(trim($values[$i]));
  389. }
  390. $pte->ptsHandle = trim($handles[$i]);
  391. $pte->ptsType = $type;
  392. // returns a nested associative array that's
  393. // $styles[$handle'][] = style 1, $styles[$handle'][] = 'style 2', etc...
  394. $styles[$pte->ptsHandle][] = $pte;
  395. }
  396. }
  397. return $styles;
  398. }
  399. /**
  400. * @param string $ptHandle
  401. * @return PageTheme
  402. */
  403. public function getByHandle($ptHandle) {
  404. $where = 'ptHandle = ?';
  405. $args = array($ptHandle);
  406. $pt = PageTheme::populateThemeQuery($where, $args);
  407. return $pt;
  408. }
  409. /**
  410. * @param int $ptID
  411. * @return PageTheme
  412. */
  413. public function getByID($ptID) {
  414. $where = 'ptID = ?';
  415. $args = array($ptID);
  416. $pt = PageTheme::populateThemeQuery($where, $args);
  417. return $pt;
  418. }
  419. protected function populateThemeQuery($where, $args) {
  420. $db = Loader::db();
  421. $row = $db->GetRow("select ptID, ptHandle, ptDescription, pkgID, ptName from PageThemes where {$where}", $args);
  422. if ($row['ptID']) {
  423. $pl = new PageTheme;
  424. $pl->setPropertiesFromArray($row);
  425. $pkgHandle = $pl->getPackageHandle();
  426. if ($row['pkgID'] > 0) {
  427. if (is_dir(DIR_PACKAGES . '/' . $pkgHandle)) {
  428. $pl->ptDirectory = DIR_PACKAGES . '/' . $pkgHandle . '/' . DIRNAME_THEMES . '/' . $row['ptHandle'];
  429. $url = BASE_URL . DIR_REL;
  430. } else {
  431. $pl->ptDirectory = DIR_PACKAGES_CORE . '/' . $pkgHandle . '/' . DIRNAME_THEMES . '/' . $row['ptHandle'];
  432. $url = ASSETS_URL;
  433. }
  434. $pl->ptURL = $url . '/' . DIRNAME_PACKAGES . '/' . $pkgHandle . '/' . DIRNAME_THEMES . '/' . $row['ptHandle'];
  435. } else if (is_dir(DIR_FILES_THEMES . '/' . $row['ptHandle'])) {
  436. $pl->ptDirectory = DIR_FILES_THEMES . '/' . $row['ptHandle'];
  437. $pl->ptURL = BASE_URL . DIR_REL . '/' . DIRNAME_THEMES . '/' . $row['ptHandle'];
  438. } else {
  439. $pl->ptDirectory = DIR_FILES_THEMES_CORE . '/' . $row['ptHandle'];
  440. $pl->ptURL = ASSETS_URL . '/' . DIRNAME_THEMES . '/' . $row['ptHandle'];
  441. }
  442. return $pl;
  443. }
  444. }
  445. public function add($ptHandle, $pkg = null) {
  446. if (is_object($pkg)) {
  447. if (is_dir(DIR_PACKAGES . '/' . $pkg->getPackageHandle())) {
  448. $dir = DIR_PACKAGES . '/' . $pkg->getPackageHandle() . '/' . DIRNAME_THEMES . '/' . $ptHandle;
  449. } else {
  450. $dir = DIR_PACKAGES_CORE . '/' . $pkg->getPackageHandle() . '/' . DIRNAME_THEMES . '/' . $ptHandle;
  451. }
  452. $pkgID = $pkg->getPackageID();
  453. } else if (is_dir(DIR_FILES_THEMES . '/' . $ptHandle)) {
  454. $dir = DIR_FILES_THEMES . '/' . $ptHandle;
  455. $pkgID = 0;
  456. } else {
  457. $dir = DIR_FILES_THEMES_CORE . '/' . $ptHandle;
  458. $pkgID = 0;
  459. }
  460. $l = PageTheme::install($dir, $ptHandle, $pkgID);
  461. return $l;
  462. }
  463. // grabs all files in theme that are PHP based (or html if we go that route) and then
  464. // lists them out, by type, allowing people to install them as page type, etc...
  465. public function getFilesInTheme() {
  466. Loader::model('collection_types');
  467. Loader::model('single_page');
  468. $dh = Loader::helper('file');
  469. $ctlist = CollectionType::getList();
  470. $cts = array();
  471. foreach($ctlist as $ct) {
  472. $cts[] = $ct->getCollectionTypeHandle();
  473. }
  474. $filesTmp = $dh->getDirectoryContents($this->ptDirectory);
  475. foreach($filesTmp as $f) {
  476. if (strrchr($f, '.') == PageTheme::THEME_EXTENSION) {
  477. $fHandle = substr($f, 0, strpos($f, '.'));
  478. if ($f == FILENAME_THEMES_VIEW) {
  479. $type = PageThemeFile::TFTYPE_VIEW;
  480. } else if ($f == FILENAME_THEMES_DEFAULT) {
  481. $type = PageThemeFile::TFTYPE_DEFAULT;
  482. } else if (in_array($f, SinglePage::getThemeableCorePages())) {
  483. $type = PageThemeFile::TFTYPE_SINGLE_PAGE;
  484. } else if (in_array($fHandle, $cts)) {
  485. $type = PageThemeFile::TFTYPE_PAGE_TYPE_EXISTING;
  486. } else {
  487. $type = PageThemeFile::TFTYPE_PAGE_TYPE_NEW;
  488. }
  489. $pf = new PageThemeFile();
  490. $pf->setFilename($f);
  491. $pf->setType($type);
  492. $files[] = $pf;
  493. }
  494. }
  495. return $files;
  496. }
  497. private static function getThemeNameAndDescription($dir) {
  498. $res = new stdClass;
  499. $res->ptName = t('(No Name)');
  500. $res->ptDescription = t('(No Description)');
  501. if (file_exists($dir . '/' . FILENAME_THEMES_DESCRIPTION)) {
  502. $con = file($dir . '/' . FILENAME_THEMES_DESCRIPTION);
  503. $res->ptName = trim($con[0]);
  504. $res->ptDescription = trim($con[1]);
  505. }
  506. return $res;
  507. }
  508. public static function exportList($xml) {
  509. $nxml = $xml->addChild('themes');
  510. $list = PageTheme::getList();
  511. $pst = PageTheme::getSiteTheme();
  512. foreach($list as $pt) {
  513. $activated = 0;
  514. if ($pst->getThemeID() == $pt->getThemeID()) {
  515. $activated = 1;
  516. }
  517. $type = $nxml->addChild('theme');
  518. $type->addAttribute('handle', $pt->getThemeHandle());
  519. $type->addAttribute('package', $pt->getPackageHandle());
  520. $type->addAttribute('activated', $activated);
  521. }
  522. }
  523. protected function install($dir, $ptHandle, $pkgID) {
  524. if (is_dir($dir)) {
  525. $db = Loader::db();
  526. $cnt = $db->getOne("select count(ptID) from PageThemes where ptHandle = ?", array($ptHandle));
  527. if ($cnt > 0) {
  528. throw new Exception(PageTheme::E_THEME_INSTALLED);
  529. }
  530. $res = PageTheme::getThemeNameAndDescription($dir);
  531. $ptName = $res->ptName;
  532. $ptDescription = $res->ptDescription;
  533. $db->query("insert into PageThemes (ptHandle, ptName, ptDescription, pkgID) values (?, ?, ?, ?)", array($ptHandle, $ptName, $ptDescription, $pkgID));
  534. $env = Environment::get();
  535. $env->clearOverrideCache();
  536. return PageTheme::getByID($db->Insert_ID());
  537. }
  538. }
  539. public function getThemeID() {return $this->ptID;}
  540. public function getThemeName() {return $this->ptName;}
  541. public function getPackageID() {return $this->pkgID;}
  542. public function getPackageHandle() {
  543. return PackageList::getHandle($this->pkgID);
  544. }
  545. public function getThemeHandle() {return $this->ptHandle;}
  546. public function getThemeDescription() {return $this->ptDescription;}
  547. public function getThemeDirectory() {return $this->ptDirectory;}
  548. public function getThemeURL() {return $this->ptURL;}
  549. public function getThemeEditorCSS() {return $this->ptURL . '/' . PageTheme::FILENAME_TYPOGRAPHY_CSS;}
  550. public function isUninstallable() {
  551. return ($this->ptDirectory != DIR_FILES_THEMES_CORE . '/' . $this->getThemeHandle());
  552. }
  553. public function getThemeThumbnail() {
  554. if (file_exists($this->ptDirectory . '/' . FILENAME_THEMES_THUMBNAIL)) {
  555. $src = $this->ptURL . '/' . FILENAME_THEMES_THUMBNAIL;
  556. } else {
  557. $src = ASSETS_URL_THEMES_NO_THUMBNAIL;
  558. }
  559. $h = Loader::helper('html');
  560. $img = $h->image($src, THEMES_THUMBNAIL_WIDTH, THEMES_THUMBNAIL_HEIGHT, array('class' => 'ccm-icon-theme'));
  561. return $img;
  562. }
  563. public function applyToSite() {
  564. $db = Loader::db();
  565. $r = $db->query("update CollectionVersions inner join Pages on CollectionVersions.cID = Pages.cID left join Packages on Pages.pkgID = Packages.pkgID set CollectionVersions.ptID = ? where cIsTemplate = 0 and (Packages.pkgHandle <> 'core' or pkgHandle is null or CollectionVersions.ctID > 0)", array($this->ptID));
  566. }
  567. public function getSiteTheme() {
  568. $c = Page::getByID(HOME_CID);
  569. return PageTheme::getByID($c->getCollectionThemeID());
  570. }
  571. public function uninstall() {
  572. $db = Loader::db();
  573. Loader::model('page_theme_archive');
  574. //$pla = new PageThemeArchive($this->ptHandle);
  575. //$pla->uninstall();
  576. $db->query("delete from PageThemes where ptID = ?", array($this->ptID));
  577. $env = Environment::get();
  578. $env->clearOverrideCache();
  579. }
  580. }