00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 class Mage_Core_Model_Design_Package
00029 {
00030 const DEFAULT_AREA = 'frontend';
00031 const DEFAULT_PACKAGE = 'default';
00032 const DEFAULT_THEME = 'default';
00033 const FALLBACK_THEME = 'default';
00034
00035 private static $_regexMatchCache = array();
00036 private static $_customThemeTypeCache = array();
00037
00038
00039
00040
00041
00042
00043 protected $_store = null;
00044
00045
00046
00047
00048
00049
00050 protected $_area;
00051
00052
00053
00054
00055
00056
00057 protected $_name;
00058
00059
00060
00061
00062
00063
00064 protected $_theme;
00065
00066
00067
00068
00069
00070
00071 protected $_rootDir;
00072
00073 protected $_config = null;
00074
00075
00076
00077
00078
00079
00080
00081 public function setStore($store)
00082 {
00083 $this->_store = $store;
00084 return $this;
00085 }
00086
00087
00088
00089
00090
00091
00092 public function getStore()
00093 {
00094 if ($this->_store === null) {
00095 return Mage::app()->getStore();
00096 }
00097 return $this->_store;
00098 }
00099
00100
00101
00102
00103
00104
00105
00106 public function setArea($area)
00107 {
00108 $this->_area = $area;
00109 return $this;
00110 }
00111
00112
00113
00114
00115
00116
00117 public function getArea()
00118 {
00119 if (is_null($this->_area)) {
00120 $this->_area = self::DEFAULT_AREA;
00121 }
00122 return $this->_area;
00123 }
00124
00125
00126
00127
00128
00129
00130
00131
00132 public function setPackageName($name = '')
00133 {
00134 if (empty($name)) {
00135
00136 $customPackage = $this->_checkUserAgentAgainstRegexps('design/package/ua_regexp');
00137 if ($customPackage) {
00138 $this->_name = $customPackage;
00139 }
00140 else {
00141 $this->_name = Mage::getStoreConfig('design/package/name', $this->getStore());
00142 }
00143 }
00144 else {
00145 $this->_name = $name;
00146 }
00147
00148 if (!$this->designPackageExists($this->_name, $this->getArea())) {
00149 $this->_name = self::DEFAULT_PACKAGE;
00150 }
00151 return $this;
00152 }
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 public function setAllGetOld($storePackageArea)
00164 {
00165 $oldValues = array();
00166 if (array_key_exists('store', $storePackageArea)) {
00167 $oldValues['store'] = $this->getStore();
00168 $this->setStore($storePackageArea['store']);
00169 }
00170 if (array_key_exists('package', $storePackageArea)) {
00171 $oldValues['package'] = $this->getPackageName();
00172 $this->setPackageName($storePackageArea['package']);
00173 }
00174 if (array_key_exists('area', $storePackageArea)) {
00175 $oldValues['area'] = $this->getArea();
00176 $this->setArea($storePackageArea['area']);
00177 }
00178 return $oldValues;
00179 }
00180
00181
00182
00183
00184
00185
00186 public function getPackageName()
00187 {
00188 if (null === $this->_name) {
00189 $this->setPackageName();
00190 }
00191 return $this->_name;
00192 }
00193
00194 public function designPackageExists($packageName, $area = self::DEFAULT_AREA)
00195 {
00196 return is_dir(Mage::getBaseDir('design') . DS . $area . DS . $packageName);
00197 }
00198
00199
00200
00201
00202
00203
00204 public function setTheme()
00205 {
00206 switch (func_num_args()) {
00207 case 1:
00208 foreach (array('layout', 'template', 'skin', 'locale') as $type) {
00209 $this->_theme[$type] = func_get_arg(0);
00210 }
00211 break;
00212
00213 case 2:
00214 $this->_theme[func_get_arg(0)] = func_get_arg(1);
00215 break;
00216
00217 default:
00218 throw Mage::exception(Mage::helper('core')->__('Wrong number of arguments for %s', __METHOD__));
00219 }
00220 return $this;
00221 }
00222
00223 public function getTheme($type)
00224 {
00225 if (empty($this->_theme[$type])) {
00226 $this->_theme[$type] = Mage::getStoreConfig('design/theme/'.$type, $this->getStore());
00227 if ($type!=='default' && empty($this->_theme[$type])) {
00228 $this->_theme[$type] = $this->getTheme('default');
00229 if (empty($this->_theme[$type])) {
00230 $this->_theme[$type] = self::DEFAULT_THEME;
00231 }
00232
00233
00234 }
00235 }
00236
00237
00238
00239
00240 $customThemeType = $this->_checkUserAgentAgainstRegexps("design/theme/{$type}_ua_regexp");
00241 if ($customThemeType) {
00242 $this->_theme[$type] = $customThemeType;
00243 }
00244
00245 return $this->_theme[$type];
00246 }
00247
00248 public function getDefaultTheme()
00249 {
00250 return self::DEFAULT_THEME;
00251 }
00252
00253 public function updateParamDefaults(array &$params)
00254 {
00255 if ($this->getStore()) {
00256 $params['_store'] = $this->getStore();
00257 }
00258 if (empty($params['_area'])) {
00259 $params['_area'] = $this->getArea();
00260 }
00261 if (empty($params['_package'])) {
00262 $params['_package'] = $this->getPackageName();
00263 }
00264 if (empty($params['_theme'])) {
00265 $params['_theme'] = $this->getTheme( (isset($params['_type'])) ? $params['_type'] : '' );
00266 }
00267 if (empty($params['_default'])) {
00268 $params['_default'] = false;
00269 }
00270 return $this;
00271 }
00272
00273 public function getBaseDir(array $params)
00274 {
00275 $this->updateParamDefaults($params);
00276 $baseDir = (empty($params['_relative']) ? Mage::getBaseDir('design').DS : '').
00277 $params['_area'].DS.$params['_package'].DS.$params['_theme'].DS.$params['_type'];
00278 return $baseDir;
00279 }
00280
00281 public function getSkinBaseDir(array $params=array())
00282 {
00283 $this->updateParamDefaults($params);
00284 $baseDir = (empty($params['_relative']) ? Mage::getBaseDir('skin').DS : '').
00285 $params['_area'].DS.$params['_package'].DS.$params['_theme'];
00286 return $baseDir;
00287 }
00288
00289 public function getLocaleBaseDir(array $params=array())
00290 {
00291 $this->updateParamDefaults($params);
00292 $baseDir = (empty($params['_relative']) ? Mage::getBaseDir('design').DS : '').
00293 $params['_area'].DS.$params['_package'].DS.$params['_theme'] . DS . 'locale' . DS .
00294 Mage::app()->getLocale()->getLocaleCode();
00295 return $baseDir;
00296 }
00297
00298 public function getSkinBaseUrl(array $params=array())
00299 {
00300 $this->updateParamDefaults($params);
00301 $baseUrl = Mage::getBaseUrl('skin', isset($params['_secure'])?(bool)$params['_secure']:null)
00302 .$params['_area'].'/'.$params['_package'].'/'.$params['_theme'].'/';
00303 return $baseUrl;
00304 }
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325 public function validateFile($file, array $params)
00326 {
00327 Varien_Profiler::start(__METHOD__);
00328 switch ($params['_type']) {
00329 case 'skin':
00330 $fileName = $this->getSkinBaseDir($params);
00331 break;
00332
00333 case 'locale':
00334 $fileName = $this->getLocaleBasedir($params);
00335 break;
00336
00337 default:
00338 $fileName = $this->getBaseDir($params);
00339 break;
00340 }
00341 $fileName.= DS.$file;
00342
00343 $testFile = (empty($params['_relative']) ? '' : Mage::getBaseDir('design').DS) . $fileName;
00344
00345 if ($this->getDefaultTheme()!==$params['_theme'] && !file_exists($testFile)) {
00346 return false;
00347 }
00348 Varien_Profiler::stop(__METHOD__);
00349 return $fileName;
00350 }
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361 public function getFilename($file, array $params)
00362 {
00363 Varien_Profiler::start(__METHOD__);
00364 $this->updateParamDefaults($params);
00365 $filename = $this->validateFile($file, $params);
00366 if (false===$filename) {
00367 $params['_theme'] = $this->getFallbackTheme();
00368 $filename = $this->validateFile($file, $params);
00369 if (false===$filename) {
00370 if ($this->getDefaultTheme()===$params['_theme']) {
00371 return $params['_default'];
00372 }
00373 $params['_theme'] = $this->getDefaultTheme();
00374 $filename = $this->validateFile($file, $params);
00375 if (false===$filename) {
00376 return $params['_default'];
00377 }
00378 }
00379 }
00380 Varien_Profiler::stop(__METHOD__);
00381 return $filename;
00382 }
00383
00384 public function getFallbackTheme()
00385 {
00386 return Mage::getStoreConfig('design/theme/default', $this->getStore());
00387 }
00388
00389 public function getLayoutFilename($file, array $params=array())
00390 {
00391 $params['_type'] = 'layout';
00392 return $this->getFilename($file, $params);
00393 }
00394
00395 public function getTemplateFilename($file, array $params=array())
00396 {
00397 $params['_type'] = 'template';
00398 return $this->getFilename($file, $params);
00399 }
00400
00401 public function getLocaleFileName($file, array $params=array())
00402 {
00403 $params['_type'] = 'locale';
00404 return $this->getFilename($file, $params);
00405 }
00406
00407
00408
00409
00410
00411
00412
00413
00414 public function getSkinUrl($file=null, array $params=array())
00415 {
00416 Varien_Profiler::start(__METHOD__);
00417 if (empty($params['_type'])) {
00418 $params['_type'] = 'skin';
00419 }
00420 if (empty($params['_default'])) {
00421 $params['_default'] = false;
00422 }
00423 $this->updateParamDefaults($params);
00424 if (!empty($file)) {
00425 $filename = $this->validateFile($file, $params);
00426 if (false===$filename) {
00427
00428 $params['_theme'] = $this->getFallbackTheme();
00429 $filename = $this->validateFile($file, $params);
00430 if (false===$filename) {
00431 if ($this->getDefaultTheme()===$params['_theme']) {
00432 return $params['_default'];
00433 }
00434 $params['_theme'] = $this->getDefaultTheme();
00435 $filename = $this->validateFile($file, $params);
00436 if (false===$filename) {
00437 return $params['_default'];
00438 }
00439 }
00440
00441 }
00442 }
00443
00444 $url = $this->getSkinBaseUrl($params).(!empty($file) ? $file : '');
00445 Varien_Profiler::stop(__METHOD__);
00446 return $url;
00447 }
00448
00449 public function getPackageList()
00450 {
00451 $directory = Mage::getBaseDir('design') . DS . 'frontend';
00452 return $this->_listDirectories($directory);
00453 }
00454
00455 public function getThemeList($package = null)
00456 {
00457 $result = array();
00458
00459 if (is_null($package)){
00460 foreach ($this->getPackageList() as $package){
00461 $result[$package] = $this->getThemeList($package);
00462 }
00463 } else {
00464 $directory = Mage::getBaseDir('design') . DS . 'frontend' . DS . $package;
00465 $result = $this->_listDirectories($directory);
00466 }
00467
00468 return $result;
00469 }
00470
00471 private function _listDirectories($path, $fullPath = false){
00472 $result = array();
00473 $dir = opendir($path);
00474 if ($dir) {
00475 while ($entry = readdir($dir)) {
00476 if (substr($entry, 0, 1) == '.' || !is_dir($path . DS . $entry)){
00477 continue;
00478 }
00479 if ($fullPath) {
00480 $entry = $path . DS . $entry;
00481 }
00482 $result[] = $entry;
00483 }
00484 unset($entry);
00485 closedir($dir);
00486 }
00487
00488 return $result;
00489 }
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500 protected function _checkUserAgentAgainstRegexps($regexpsConfigPath)
00501 {
00502 if (!empty($_SERVER['HTTP_USER_AGENT'])) {
00503 if (!empty(self::$_customThemeTypeCache[$regexpsConfigPath])) {
00504 return self::$_customThemeTypeCache[$regexpsConfigPath];
00505 }
00506 $configValueSerialized = Mage::getStoreConfig($regexpsConfigPath, $this->getStore());
00507 if ($configValueSerialized) {
00508 $regexps = @unserialize($configValueSerialized);
00509 if (!empty($regexps)) {
00510 foreach ($regexps as $rule) {
00511 if (!empty(self::$_regexMatchCache[$rule['regexp']][$_SERVER['HTTP_USER_AGENT']])) {
00512 self::$_customThemeTypeCache[$regexpsConfigPath] = $rule['value'];
00513 return $rule['value'];
00514 }
00515 $regexp = $rule['regexp'];
00516 if (false === strpos($regexp, '/', 0)) {
00517 $regexp = '/' . $regexp . '/';
00518 }
00519 if (@preg_match($regexp, $_SERVER['HTTP_USER_AGENT'])) {
00520 self::$_regexMatchCache[$rule['regexp']][$_SERVER['HTTP_USER_AGENT']] = true;
00521 self::$_customThemeTypeCache[$regexpsConfigPath] = $rule['value'];
00522 return $rule['value'];
00523 }
00524 }
00525 }
00526 }
00527 }
00528 return false;
00529 }
00530 }