PageRenderTime 59ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 0ms

/assets/libs/resourse.php

https://github.com/modxcms/evolution
PHP | 483 lines | 421 code | 15 blank | 47 comment | 38 complexity | 2057e1d73fd6cae6cbe6cfc519d26c2e MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, MIT, BSD-2-Clause, Apache-2.0, BSD-3-Clause
  1. <?php
  2. /**
  3. version: 0.4.2
  4. Author:
  5. * Bumkaka from modx.im
  6. * Agel_Nash <agel_nash@xaker.ru>
  7. USE:
  8. require_once('assets/libs/resourse.php');
  9. $resourse=resourse::Instance($modx);
  10. #------------------------------------------------------
  11. * Add new document without invoke event and clear cache
  12. $resourse->document()->set('titl','Пропаганда')->set('pagetitle',$i)->save(null,false);
  13. * Add new document without invoke event and call clear cache
  14. $resourse->document()->set('titl','Пропаганда')->set('pagetitle',$i)->save(null,true);
  15. * Add new document call event and without clear cache
  16. $resourse->document()->set('titl','Пропаганда')->set('pagetitle',$i)->save(true,false);
  17. #-------------------------------------------------------
  18. #Edit resourse #13
  19. $resourse->edit(13)->set('pagetitle','new pagetitle')->save(null,false);
  20. #-------------------------------------------------------
  21. $resourse->delete(8);
  22. //JSON && PHP < 5.3
  23. $t = test::Instance();
  24. function asd($json){
  25. $t = test::Instance();
  26. foreach($json as $key=>$val){
  27. $t->set($key,$val);
  28. }
  29. }
  30. $t->fromJson($json,'asd');
  31. //JSON && PHP >= 5.3
  32. $t = test::Instance();
  33. $t->fromJson($json, function($json) use ($t){
  34. foreach($json as $key=>$val){
  35. $t->set($key,$val);
  36. }
  37. });
  38. */
  39. if(!defined('MODX_BASE_PATH')) {die('What are you doing? Get out of here!');}
  40. class resourse {
  41. static $_instance = null;
  42. private $_modx = null;
  43. private $id = 0;
  44. private $field = array();
  45. private $tv = array();
  46. private $tvid = array();
  47. private $log = array();
  48. private $edit = 0;
  49. private $default_field ;
  50. private $table=array('"'=>'_',"'"=>'_',' '=>'_','.'=>'_',','=>'_','а'=>'a','б'=>'b','в'=>'v',
  51. 'г'=>'g','д'=>'d','е'=>'e','ё'=>'e','ж'=>'zh','з'=>'z','и'=>'i','й'=>'y','к'=>'k',
  52. 'л'=>'l','м'=>'m','н'=>'n','о'=>'o','п'=>'p','р'=>'r','с'=>'s','т'=>'t','у'=>'u',
  53. 'ф'=>'f','х'=>'h','ц'=>'c','ч'=>'ch','ш'=>'sh','щ'=>'sch','ь'=>'','ы'=>'y','ъ'=>'',
  54. 'э'=>'e','ю'=>'yu','я'=>'ya','А'=>'A','Б'=>'B','В'=>'V','Г'=>'G','Д'=>'D','Е'=>'E',
  55. 'Ё'=>'E','Ж'=>'Zh','З'=>'Z','И'=>'I','Й'=>'Y','К'=>'K','Л'=>'L','М'=>'M','Н'=>'N',
  56. 'О'=>'O','П'=>'P','Р'=>'R','С'=>'S','Т'=>'T','У'=>'U','Ф'=>'F','Х'=>'H','Ц'=>'C',
  57. 'Ч'=>'Ch','Ш'=>'Sh','Щ'=>'Sch','Ь'=>'','Ы'=>'Y','Ъ'=>'','Э'=>'E','Ю'=>'Yu','Я'=>'Ya','/'=>'-',
  58. );
  59. private $set;
  60. private $flag = false;
  61. private $_table = array('site_content','site_tmplvar_contentvalues','site_tmplvars','site_templates','web_user_settings');
  62. private function __construct($modx){
  63. try{
  64. if($modx instanceof DocumentParser){
  65. $this->modx = $modx;
  66. } else throw new Exception('MODX should be instance of DocumentParser');
  67. if(!$this->makeTable()) throw new Exception('Not exists table');
  68. }catch(Exception $e){ die($e->getMessage()); }
  69. $this->get_TV();
  70. }
  71. private final function __clone(){throw new Exception('Clone is not allowed');}
  72. static public function Instance($modx){
  73. if (self::$_instance == NULL){self::$_instance = new self($modx);}
  74. return self::$_instance;
  75. }
  76. public function document($id=0){
  77. $this->newDoc = $id == 0;
  78. $this->id = $id;
  79. $this->field=array();
  80. $this->set=array();
  81. $this->default_field = array(
  82. 'type'=>'document',
  83. 'contentType'=>'text/html',
  84. 'pagetitle'=>'New document',
  85. 'longtitle'=>'',
  86. 'description'=>'',
  87. 'alias'=>'',
  88. 'link_attributes'=>'',
  89. 'published'=>'1',
  90. 'pub_date'=>'0',
  91. 'unpub_date'=>'0',
  92. 'parent'=>'0',
  93. 'isfolder'=>'0',
  94. 'introtext'=>'',
  95. 'content'=>'',
  96. 'richtext'=>'1',
  97. 'template'=>'0',
  98. 'menuindex'=>'0',
  99. 'searchable'=>'1',
  100. 'cacheable'=>'1',
  101. 'createdon'=>time(),
  102. 'createdby'=>'0',
  103. 'editedon'=>'0',
  104. 'editedby'=>'0',
  105. 'deleted'=>'0',
  106. 'deletedon'=>'0',
  107. 'deletedby'=>'0',
  108. 'publishedon'=>'0',
  109. 'publishedby'=>'0',
  110. 'menutitle'=>'',
  111. 'donthit'=>'0',
  112. 'haskeywords'=>'0',
  113. 'hasmetatags'=>'0',
  114. 'privateweb'=>'0',
  115. 'privatemgr'=>'0',
  116. 'content_dispo'=>'0',
  117. 'hidemenu'=>'1',
  118. 'alias_visible'=>'1'
  119. );
  120. $this->flag = true;
  121. return $this;
  122. }
  123. private function makeTable(){
  124. //@TODO: check exists table
  125. $flag = true;
  126. foreach($this->_table as $item){
  127. $this->_table[$item] = $this->modx->getFullTableName($item);
  128. }
  129. return $flag;
  130. }
  131. private function Uset($key){
  132. if(!isset($this->field[$key])){
  133. $this->set[$key]= "";
  134. $this->log[] = "{$key} is empty";
  135. } else {
  136. try{
  137. if(is_scalar($this->field[$key])){
  138. $this->set[$key]= $this->field[$key];
  139. } else throw new Exception("{$key} is not scalar <pre>".print_r($this->field[$key],true)."</pre>");
  140. }catch(Exception $e){ die($e->getMessage()); }
  141. }
  142. return $this;
  143. }
  144. private function invokeEvent($name,$data=array(),$flag=false){
  145. $flag = (isset($flag) && $flag!='') ? (bool)$flag : false;
  146. if($flag){
  147. $this->modx->invokeEvent($name,$data);
  148. }
  149. return $this;
  150. }
  151. public function clearCache($fire_events = null){
  152. $this->modx->clearCache('full');
  153. $this->invokeEvent('OnSiteRefresh',array(),$fire_events);
  154. }
  155. public function list_log($flush = false){
  156. echo '<pre>'.print_r($this->log,true).'</pre>';
  157. if($flush) $this->clearLog();
  158. return $this;
  159. }
  160. public function clearLog(){
  161. $this->log = array();
  162. return $this;
  163. }
  164. public function set($key,$value){
  165. if(is_scalar($value) && is_scalar($key) && !empty($key)){
  166. switch($key){
  167. case 'template': {
  168. $value = trim($value);
  169. $value = $this->setTemplate($value);
  170. break;
  171. }
  172. }
  173. $this->field[$key] = $value;
  174. }
  175. return $this;
  176. }
  177. private function setTemplate($tpl) {
  178. if(!is_numeric($tpl) || $tpl != (int) $tpl) {
  179. try{
  180. if(is_scalar($tpl)){
  181. $rs = $this->modx->db->select('id', $this->_table['site_templates'], "templatename = '{$tpl}'");
  182. if($this->modx->db->getRecordCount($rs) <= 0) throw new Exception("Template {$tpl} is not exists");
  183. $tpl = $this->modx->db->getValue($rs);
  184. } else throw new Exception("Invalid template name: ".print_r($tpl,1));
  185. }catch(Exception $e){
  186. $tpl = 0;
  187. die($e->getMessage());
  188. }
  189. }
  190. return (int)$tpl;
  191. }
  192. public function get($key){
  193. return isset($this->field[$key]) ? $this->field[$key] : null;
  194. }
  195. private function getAlias(){
  196. if ($this->modx->config['friendly_urls'] && $this->modx->config['automatic_alias'] && $this->get('alias') == ''){
  197. $alias = mb_strtolower(strtr($this->get('pagetitle'), $this->table));
  198. }else{
  199. if($this->get('alias')!=''){
  200. $alias = $this->get('alias');
  201. }else{
  202. $alias = '';
  203. }
  204. }
  205. return $this->checkAlias($alias);
  206. }
  207. public function get_TV(){
  208. $result = $this->modx->db->select('id,name', $this->_table['site_tmplvars']);
  209. while($row = $this->modx->db->getRow($result)) {
  210. $this->tv[$row['name']] = $row['id'];
  211. $this->tvid[$row['id']] = $row['name'];
  212. }
  213. }
  214. public function fromArray($data){
  215. foreach($data as $key=>$value) $this->set($key,$value);
  216. return $this;
  217. }
  218. public function edit($id){
  219. if(!$this->flag) $this->document($id);
  220. $result = $this->modx->db->select('*', $this->_table['site_content'], "id=".(int)$id);
  221. $this->fromArray($this->modx->db->getRow($result));
  222. $result = $this->modx->db->select('*', $this->_table['site_tmplvar_contentvalues'], "contentid=".(int)$id);
  223. while ($row = $this->modx->db->getRow($result)){
  224. $this->set($this->tvid[$row['tmplvarid']], $row['value']);
  225. }
  226. unset($this->field['id']);
  227. return $this;
  228. }
  229. private function systemID(){
  230. $ignore = array(
  231. 0, //empty document
  232. (int)$this->modx->config['site_start'],
  233. (int)$this->modx->config['error_page'],
  234. (int)$this->modx->config['unauthorized_page'],
  235. (int)$this->modx->config['site_unavailable_page']
  236. );
  237. $data = $this->modx->db->select('DISTINCT setting_value', $this->_table['web_user_settings'], "setting_name='login_home' AND setting_value!=''");
  238. $data = $this->modx->db->makeArray($data);
  239. foreach($data as $item){
  240. $ignore[]=(int)$item['setting_value'];
  241. }
  242. return array_unique($ignore);
  243. }
  244. public function delete($ids,$fire_events = null){
  245. //@TODO: delete with SET deleted=1
  246. $ignore = $this->systemID();
  247. $_ids = $this->cleanIDs($ids, ',', $ignore);
  248. try{
  249. if(is_array($_ids) && $_ids!=array()){
  250. $this->invokeEvent('OnBeforeEmptyTrash',array(
  251. "ids"=>$_ids
  252. ),$fire_events);
  253. $id = $this->sanitarIn($_ids);
  254. $this->modx->db->delete($this->_table['site_content'], "id IN ({$id})");
  255. $this->modx->db->delete($this->_table['site_tmplvar_contentvalues'], "contentid IN ({$id})");
  256. $this->invokeEvent('OnEmptyTrash',array(
  257. "ids"=>$_ids
  258. ),$fire_events);
  259. } else throw new Exception('Invalid IDs list for delete: <pre>'.print_r($ids,1).'</pre> please, check ignore list: <pre>'.print_r($ignore,1).'</pre>');
  260. }catch(Exception $e){ die($e->getMessage()); }
  261. return $this;
  262. }
  263. final private function cleanIDs($IDs,$sep=',',$ignore = array()) {
  264. $out=array();
  265. if(!is_array($IDs)){
  266. try{
  267. if(is_scalar($IDs)){
  268. $IDs=explode($sep, $IDs);
  269. } else {
  270. $IDs = array();
  271. throw new Exception('Invalid IDs list <pre>'.print_r($IDs,1).'</pre>');
  272. }
  273. } catch(Exception $e){ die($e->getMessage()); }
  274. }
  275. foreach($IDs as $item){
  276. $item = trim($item);
  277. if(is_numeric($item) && (int)$item>=0){ //Fix 0xfffffffff
  278. if(!empty($ignore) && in_array((int)$item, $ignore, true)){
  279. $this->log[] = 'Ignore id '.(int)$item;
  280. }else{
  281. $out[]=(int)$item;
  282. }
  283. }
  284. }
  285. print_r($ignore);
  286. $out = array_unique($out);
  287. return $out;
  288. }
  289. final protected function check($id){
  290. return (is_array($id) && $id!=array()) ? true : false;
  291. }
  292. final protected function sanitarIn($data,$sep=','){
  293. if(!is_array($data)){
  294. $data=explode($sep,$data);
  295. }
  296. $out = $this->modx->db->escape($data);
  297. $out="'".implode("','",$out)."'";
  298. return $out;
  299. }
  300. public function fromJson($data,$callback=null){
  301. try{
  302. if(is_scalar($data) && !empty($data)){
  303. $json = json_decode($data);
  304. }else throw new Exception("json is not string with json data");
  305. if ($this->jsonError($json)) {
  306. if(isset($callback) && is_callable($callback)){
  307. call_user_func_array($callback,array($json));
  308. }else{
  309. if(isset($callback)) throw new Exception("Can't call callback JSON unpack <pre>".print_r($callback,1)."</pre>");
  310. foreach($json as $key=>$val){
  311. $this->set($key,$val);
  312. }
  313. }
  314. } else throw new Exception('Error from JSON decode: <pre>'.print_r($data,1).'</pre>');
  315. }catch(Exception $e){ die($e->getMessage()); }
  316. return $this;
  317. }
  318. public function toJson($callback=null){
  319. try{
  320. $data = $this->toArray();
  321. $json = json_encode($data);
  322. if(!$this->jsonError($data,$json)) {
  323. $json = false;
  324. throw new Exception('Error from JSON decode: <pre>'.print_r($data,1).'</pre>');
  325. }
  326. }catch(Exception $e){ die($e->getMessage()); }
  327. return $json;
  328. }
  329. private function jsonError($data){
  330. $flag = false;
  331. if(!function_exists('json_last_error')){
  332. function json_last_error(){
  333. return JSON_ERROR_NONE;
  334. }
  335. }
  336. if(json_last_error() === JSON_ERROR_NONE && is_object($data) && $data instanceof stdClass){
  337. $flag = true;
  338. }
  339. return $flag;
  340. }
  341. public function toArray(){
  342. return $this->field;
  343. }
  344. private function checkAlias($alias){
  345. if($this->modx->config['friendly_urls']){
  346. $flag = false;
  347. $_alias = $this->modx->db->escape($alias);
  348. if(!$this->modx->config['allow_duplicate_alias'] || ($this->modx->config['allow_duplicate_alias'] && $this->modx->conifg['use_alias_path'])){
  349. $flag = $this->modx->db->getValue($this->modx->db->select('id', $this->_table['site_content'], "alias='{$_alias}' AND parent={$this->get('parent')}", '', 1));
  350. } else {
  351. $flag = $this->modx->db->getValue($this->modx->db->select('id', $this->_table['site_content'], "alias='{$_alias}'", '', 1));
  352. }
  353. if(($flag && $this->newDoc) || (!$this->newDoc && $flag && $this->id != $flag)){
  354. $suffix = substr($alias, -2);
  355. if(preg_match('/-(\d+)/',$suffix,$tmp) && isset($tmp[1]) && (int)$tmp[1]>1){
  356. $suffix = (int)$tmp[1] + 1;
  357. $alias = substr($alias, 0, -2) . '-'. $suffix;
  358. }else{
  359. $alias .= '-2';
  360. }
  361. $alias = $this->checkAlias($alias);
  362. }
  363. }
  364. return $alias;
  365. }
  366. public function save($fire_events = null,$clearCache = false){
  367. try{
  368. if(!$this->flag){
  369. throw new Exception('You need flush document field before set and save resource');
  370. }
  371. }catch(Exception $e){ die($e->getMessage()); }
  372. if ($this->field['pagetitle'] == '') {
  373. $this->log[] = 'Pagetitle is empty in <pre>'.print_r($this->field,true).'</pre>';
  374. return false;
  375. }
  376. $this->set('alias',$this->getAlias());
  377. $this->invokeEvent('OnBeforeDocFormSave',array (
  378. "mode" => $this->newDoc ? "new" : "upd",
  379. "id" => $this->id ? $this->id : ''
  380. ),$fire_events);
  381. $fld = $this->toArray();
  382. foreach($this->default_field as $key=>$value){
  383. if ($this->newDoc && $this->get($key) == '' && $this->get($key)!==$value){
  384. $this->set($key,$value);
  385. }
  386. $this->Uset($key,$value);
  387. unset($fld[$key]);
  388. }
  389. if (!empty($this->set)){
  390. if($this->newDoc){
  391. $this->modx->db->insert($this->set, $this->_table['site_content']);
  392. }else{
  393. $this->modx->db->update($this->set, $this->_table['site_content'], "id = '{$this->id}'");
  394. }
  395. }
  396. if($this->newDoc) $this->id = $this->modx->db->getInsertId();
  397. foreach($fld as $key=>$value){
  398. if ($value=='') continue;
  399. if ($this->tv[$key]!=''){
  400. $fields = array(
  401. 'tmplvarid' => $this->tv[$key],
  402. 'contentid' => $this->id,
  403. 'value' => $this->modx->db->escape($value),
  404. );
  405. $rs = $this->modx->db->select('value', $this->_table['site_tmplvar_contentvalues'], "contentid = '{$fields['contentid']}' AND tmplvarid = '{$fields['tmplvarid']}'");
  406. if ($row = $this->modx->db->getRow($rs)) {
  407. if ($row['value'] != $value) {
  408. $this->modx->db->update($fields, $this->_table['site_tmplvar_contentvalues'], "contentid = '{$fields['contentid']}' AND tmplvarid = '{$fields['tmplvarid']}'");
  409. }
  410. }else{
  411. $this->modx->db->insert($fields, $this->_table['site_tmplvar_contentvalues']);
  412. }
  413. }
  414. }
  415. $this->invokeEvent('OnDocFormSave',array (
  416. "mode" => $this->newDoc ? "new" : "upd",
  417. "id" => $this->id
  418. ),$fire_events);
  419. if($clearCache){
  420. $this->clearCache($fire_events);
  421. }
  422. $this->flag = false;
  423. return $this->id;
  424. }
  425. }