PageRenderTime 46ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/solar/source/miku/Miku/Emerge.php

https://bitbucket.org/Sanakan/noise
PHP | 384 lines | 297 code | 47 blank | 40 comment | 28 complexity | fede5aabfe4443e63fe722dd07903025 MD5 | raw file
Possible License(s): MIT
  1. <?php
  2. /**
  3. *
  4. * Miku_Emerge class.
  5. *
  6. * @category Miku_Emerge
  7. *
  8. * @package Miku_Emerge General-purpose component helpers.
  9. *
  10. * @author
  11. *
  12. * @license http://opensource.org/licenses/bsd-license.php BSD
  13. *
  14. * @version $Id: Emerge.php
  15. *
  16. */
  17. abstract class Miku_Emerge extends Solar_Base
  18. {
  19. protected $_Miku_Emerge = array(
  20. 'cache' => array(
  21. 'adapter' => 'Solar_Cache_Adapter_None',
  22. ),
  23. 'catalog' => array(
  24. 'classes' => array('Miku_Self', 'Miku_Service'),
  25. ),
  26. 'related' => array(),
  27. );
  28. public $name = null;
  29. protected $_related = array();
  30. protected $_default = array();
  31. protected $_type = null;
  32. protected $_model;
  33. protected $_catalog;
  34. protected $_factor = null;
  35. protected $_factor_class = 'Miku_Emerge_Factor';
  36. protected $_cache;
  37. protected $_cache_key = null;
  38. protected $_cache_class = 'Miku_Emerge_Cache';
  39. protected $_view;
  40. protected $_view_object;
  41. protected $_tpl = null;
  42. protected $_view_class = 'Solar_View';
  43. protected $_helper_class = array();
  44. protected $_errors = array();
  45. protected $_output = null;
  46. protected function _postConstruct()
  47. {
  48. parent::_postConstruct();
  49. $this->_fixCache();
  50. $this->_cache = Solar::factory($this->_cache_class, array(
  51. 'cache' => $this->_config['cache'],
  52. ));
  53. $this->_cache->setSense($this);
  54. }
  55. public function __set($key, $val)
  56. {
  57. throw $this->_exception('ERR_NO_SUCH_PROPERTY', array(
  58. 'class' => get_class($this),
  59. 'property' => $key,
  60. ));
  61. }
  62. public function __get($key)
  63. {
  64. throw $this->_exception('ERR_NO_SUCH_PROPERTY', array(
  65. 'class' => get_class($this),
  66. 'property' => $key,
  67. ));
  68. }
  69. /*
  70. * $sense string
  71. * $spec array
  72. */
  73. public function express($sense,$spec = null)
  74. {
  75. if (in_array($sense, $this->_default)) {
  76. $entry = array();
  77. $entry['dependency'] = "emerge/" . $sense;
  78. $key = $this->_cache->entry($entry);
  79. $result = $this->_cache->fetch($key);
  80. if ($result !== false) {
  81. // found some data!
  82. return $result;
  83. }
  84. }
  85. $this->_fixFactor();
  86. $this->_fixName();
  87. if(! $this->_factor[$sense]) {
  88. throw $this->_exception('ERR_EXPRESS_NOT_FOUND', array(
  89. 'class' => get_class($this),
  90. 'sense' => $sense,
  91. ));
  92. }
  93. if($spec !== null){
  94. //only load keys that already exist in factor data
  95. $this->_factor->load(array($sense => $spec));
  96. }
  97. if(isset($this->_factor[$sense]['view'])){
  98. $this->_view = $this->_factor[$sense]['view'];
  99. unset($this->_factor[$sense]['view']);
  100. }else {
  101. $this->_view = $sense;
  102. }
  103. $this->_express($spec);
  104. if(is_null($this->_output) && $this->_view){
  105. $this->_render();
  106. }
  107. return $this->_output;
  108. }
  109. /*
  110. * $sense string
  111. */
  112. protected function _express($spec)
  113. {
  114. $factor = $this->_factor[$this->_view];
  115. if($factor['cache_key'] || $factor['dependency'] ) {
  116. $this->_cache_key = $this->_cache->entry($factor);
  117. $result = $this->_cache->fetch($this->_cache_key);
  118. if ($result !== false) {
  119. // found some data!
  120. return $result;
  121. }
  122. }
  123. $this->_setup();
  124. $method = str_replace('-', ' ', $this->_view);
  125. $method = ucwords(trim($method));
  126. $method = 'as' . str_replace(' ', '', $method);
  127. if (method_exists($this, $method)) {
  128. $this->_preExpress();
  129. call_user_func_array(
  130. array($this, $method),
  131. $factor
  132. );
  133. $this->_postExpress();
  134. }else {
  135. return false;
  136. }
  137. }
  138. protected function _setup()
  139. {
  140. $this->_catalog = Solar::dependency(
  141. 'Miku_Emerge_Catalog',
  142. $this->_config['catalog']
  143. );
  144. $this->_model = Solar_Registry::get("model_catalog");
  145. $this->related = $this->_config['related'];
  146. try {
  147. $type = Solar_Registry::get('mimic_type');
  148. }catch (Exception $e) {
  149. $type = Solar_Config::get('Solar','visit_type');
  150. Solar_Registry::set('mimic_type', $type);
  151. }
  152. $this->_type = $type;
  153. }
  154. protected function _preExpress()
  155. {
  156. }
  157. protected function _render()
  158. {
  159. // set up a view object, its template paths,
  160. // need actions registed view
  161. if(! $this->_view_object) {
  162. try {
  163. $this->_view_object = Solar_Registry::get('view');
  164. }catch (Exception $e) {
  165. $this->_view_object = Solar::factory($this->_view_class);
  166. $this->_addViewHelpers();
  167. Solar_Registry::set('view', $this->_view_object);
  168. $this->_view_object->visitor = $this->_catalog->visitor;
  169. }
  170. }
  171. $this->_addViewTemplates();
  172. $class = get_class($this);
  173. $this->_view_object->getHelper('getTextRaw')->setClass($class);
  174. $this->_view_object->assign($this);
  175. $this->_view_object->errors = $this->_errors;
  176. $this->_renderView();
  177. if (!is_null($this->_output) && !in_array($this->_view, $this->_default)) {
  178. $this->_cache->add($this->_cache_key ,$this->_output);
  179. }
  180. }
  181. protected function _addViewTemplates()
  182. {
  183. if($this->_type) {
  184. $type = ucfirst($this->_type);
  185. }
  186. // get the parents of the current class, including self
  187. $stack = array_reverse(Solar_Class::parents($this, true));
  188. // remove Solar_Base
  189. array_pop($stack);
  190. // convert underscores to slashes, and add /View
  191. foreach ($stack as $key => $val) {
  192. $stack[$key] = str_replace('_', '/', $val)
  193. . '/View'
  194. . $type === "Normal" ? null : "/$type";
  195. }
  196. // done, add the stack
  197. $this->_view_object->addTemplatePath($stack);
  198. }
  199. protected function _addViewHelpers()
  200. {
  201. // start with requested helper classes
  202. $stack = $this->_helper_class;
  203. // find vendors, disregarding Solar itself (since Solar_View will
  204. // add that anyway)
  205. $vendors = Solar_Class::vendors($this);
  206. array_shift($vendors);
  207. // add each vendor to the stack in turn
  208. foreach ($vendors as $vendor) {
  209. $stack[] = "{$vendor}_View_Helper";
  210. }
  211. // set the helper classes on the view object
  212. $this->_view_object->addHelperClass($stack);
  213. }
  214. protected function _renderView()
  215. {
  216. if(in_array('sketch', $this->_related)) {
  217. $this->_catalog->sketch->express('tpl', $this, $this->_view);
  218. }
  219. $tpl = $this->_view . ".php";
  220. try {
  221. $this->_output = $this->_view_object->fetch($tpl);
  222. } catch (Solar_View_Exception_TemplateNotFound $e) {
  223. throw $this->_exception('ERR_VIEW_NOT_FOUND', array(
  224. 'path' => $e->getInfo('path'),
  225. 'name' => $e->getInfo('name'),
  226. ));
  227. }
  228. }
  229. protected function _postExpress()
  230. {
  231. if($this->_view && in_array($this->_view, $this->_default)) {
  232. $entry = array();
  233. $entry['dependency'] = "emerge/" . $this->_view;
  234. $key = $this->_cache->entry($entry);
  235. $this->_cache->add($key ,$this->_output);
  236. }
  237. }
  238. protected function _sketch()
  239. {
  240. }
  241. protected function _fixFactor()
  242. {
  243. if (empty($this->_factor_class)) {
  244. $class = $this->_stack->load('Factor', false);
  245. if (! $class) {
  246. $class = 'Miku_Emerge_Factor';
  247. }
  248. $this->_factor_class = $class;
  249. }
  250. $this->_factor = Solar::factory($this->_factor_class);
  251. }
  252. protected function _fixName()
  253. {
  254. if(isset($this->_factor->sense_name)){
  255. $this->name = $this->_factor->sense_name;
  256. }else {
  257. $class = get_class($this);
  258. $pos = strrpos($class, '_');
  259. $this->name = substr($class, $pos + 1);
  260. $this->name = preg_replace(
  261. '/([a-z])([A-Z])/',
  262. '$1-$2',
  263. $this->name
  264. );
  265. $this->name = strtolower($this->sense_name);
  266. }
  267. }
  268. protected function _fixCache()
  269. {
  270. // make sure we have a cache class
  271. if (empty($this->_cache_class)) {
  272. $class = $this->_stack->load('Cache', false);
  273. if (! $class) {
  274. $class = 'Miku_Emerge_Cache';
  275. }
  276. $this->_cache_class = $class;
  277. }
  278. }
  279. protected function _fire($signal)
  280. {
  281. //$singal began with ":" or will be pushed with "Miku:"
  282. if($signal[0] == ':') {
  283. $event = get_class($this) . $signal;
  284. }else {
  285. $event = 'Miku:' . $signal;
  286. }
  287. Miku::fireEvent($event);
  288. }
  289. //help method to attach
  290. //$callback :singal, $this, someMethod OR signal, $this, someMethod
  291. protected function _attach($callback)
  292. {
  293. settype($callback, 'array');
  294. $signal = array_shift($callback);
  295. if($signal[0] == ':') {
  296. $event = get_class($this) . $signal;
  297. }else {
  298. $event = 'Miku:' . $signal;
  299. }
  300. Miku::attachEvent($event, $callback);
  301. }
  302. protected function _error($key, $replace = null)
  303. {
  304. $this->_errors[] = $this->locale($key, 1, $replace);
  305. $this->asError();
  306. }
  307. public function asError()
  308. {
  309. }
  310. public function getFactor()
  311. {
  312. return $this->_factor;
  313. }
  314. public function getRelated($alias)
  315. {
  316. if($this->_related[$alias]) {
  317. $this->_related[$alias] = $this->_catalog->{$alias};
  318. return $this->_related[$alias];
  319. }
  320. }
  321. public function getCache()
  322. {
  323. return $this->_cache;
  324. }
  325. public function getCacheKeyPrefix()
  326. {
  327. return Solar_Class::vendor($this);
  328. }
  329. public function output()
  330. {
  331. return $this->_output;
  332. }
  333. public function setView($view)
  334. {
  335. $this->_view_object = $view;
  336. }
  337. }