PageRenderTime 40ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/baser/controllers/contents_controller.php

https://github.com/hashing/basercms
PHP | 549 lines | 332 code | 67 blank | 150 comment | 64 complexity | 9769fd42be419f8844ebe595485cfe73 MD5 | raw file
Possible License(s): MIT
  1. <?php
  2. /* SVN FILE: $Id$ */
  3. /**
  4. * コンテンツコントローラー
  5. *
  6. * PHP versions 5
  7. *
  8. * baserCMS : Based Website Development Project <http://basercms.net>
  9. * Copyright 2008 - 2012, baserCMS Users Community <http://sites.google.com/site/baserusers/>
  10. *
  11. * @copyright Copyright 2008 - 2012, baserCMS Users Community
  12. * @link http://basercms.net baserCMS Project
  13. * @package baser.controllers
  14. * @since baserCMS v 0.1.0
  15. * @version $Revision$
  16. * @modifiedby $LastChangedBy$
  17. * @lastmodified $Date$
  18. * @license http://basercms.net/license/index.html
  19. */
  20. /**
  21. * コンテンツコントローラー
  22. *
  23. * @package cake
  24. * @subpackage cake.baser.controllers
  25. */
  26. class ContentsController extends AppController {
  27. /**
  28. * クラス名
  29. *
  30. * @var array
  31. * @access public
  32. */
  33. var $name = 'Contents';
  34. /**
  35. * モデル
  36. *
  37. * @var array
  38. * @access public
  39. */
  40. var $uses = array('Content', 'Page');
  41. /**
  42. * コンポーネント
  43. *
  44. * @var array
  45. * @access public
  46. */
  47. var $components = array('BcAuth','Cookie','BcAuthConfigure');
  48. /**
  49. * ヘルパー
  50. *
  51. * @var array
  52. * @access public
  53. */
  54. var $helpers = array(BC_TEXT_HELPER, BC_FORM_HELPER);
  55. /**
  56. * beforeFilter
  57. *
  58. * @return void
  59. * @access public
  60. */
  61. function beforeFilter() {
  62. parent::beforeFilter();
  63. $this->Security->enabled = false;
  64. // 認証設定
  65. $this->BcAuth->allow('search','get_page_list_recursive');
  66. if(!empty($this->params['admin'])) {
  67. $this->subMenuElements = array('site_configs', 'contents');
  68. $this->crumbs = array(
  69. array('name' => 'システム設定', 'url' => array('controller' => 'site_configs', 'action' => 'form')),
  70. array('name' => '検索インデックス管理', 'url' => array('controller' => 'contents', 'action' => 'index'))
  71. );
  72. }
  73. }
  74. /**
  75. * コンテンツ検索
  76. *
  77. * @return void
  78. * @access public
  79. */
  80. function search() {
  81. $datas = array();
  82. $query = array();
  83. $default = array('named' => array('num' => 10));
  84. $this->setViewConditions('Content', array('default' => $default, 'type' => 'get'));
  85. if(!empty($this->data['Content'])) {
  86. foreach($this->data['Content'] as $key => $value) {
  87. $this->data['Content'][$key] = h($value);
  88. }
  89. }
  90. if(!empty($this->params['url']['q'])) {
  91. $this->paginate = array(
  92. 'conditions'=> $this->_createSearchConditions($this->data),
  93. 'order' => 'Content.priority DESC, Content.modified DESC, Content.id',
  94. 'limit' => $this->passedArgs['num']
  95. );
  96. $datas = $this->paginate('Content');
  97. $query = $this->_parseQuery($this->params['url']['q']);
  98. }
  99. $this->set('query', $query);
  100. $this->set('datas', $datas);
  101. $this->pageTitle = '検索結果一覧';
  102. }
  103. /**
  104. * 検索キーワードを分解し配列に変換する
  105. *
  106. * @param string $query
  107. * @return array
  108. * @access protected
  109. */
  110. function _parseQuery($query) {
  111. $query = str_replace(' ', ' ', $query);
  112. if(strpos($query, ' ') !== false) {
  113. $query = explode(' ', $query);
  114. } else {
  115. $query = array($query);
  116. }
  117. return h($query);
  118. }
  119. /**
  120. * 検索条件を生成する
  121. *
  122. * @param array $data
  123. * @return array $conditions
  124. * @access protected
  125. */
  126. function _createSearchConditions($data) {
  127. $conditions = array('Content.status' => true);
  128. $query = '';
  129. unset($data['Content']['key']);
  130. unset($data['Content']['fields']);
  131. if(isset($data['Content']['q'])) {
  132. $query = $data['Content']['q'];
  133. unset($data['Content']['q']);
  134. }
  135. if(isset($data['Content']['c'])) {
  136. if($data['Content']['c']) {
  137. $data['Content']['category'] = $data['Content']['c'];
  138. }
  139. unset($data['Content']['c']);
  140. }
  141. if(isset($data['Content']['m'])) {
  142. if($data['Content']['m']) {
  143. $data['Content']['model'] = $data['Content']['m'];
  144. }
  145. unset($data['Content']['m']);
  146. }
  147. $conditions = am($conditions, $this->postConditions($data));
  148. if($query) {
  149. $query = $this->_parseQuery($query);
  150. foreach($query as $key => $value) {
  151. $conditions['and'][$key]['or'][] = array('Content.title LIKE' => "%{$value}%");
  152. $conditions['and'][$key]['or'][] = array('Content.detail LIKE' => "%{$value}%");
  153. }
  154. }
  155. return $conditions;
  156. }
  157. /**
  158. * ページリストを取得する
  159. *
  160. * @param mixid $parentCategoryId / '' / 0
  161. * @return type
  162. * @access public
  163. */
  164. function get_page_list_recursive($parentCategoryId = null, $recursive = null) {
  165. return $this->__getPageListRecursive($parentCategoryId, $recursive);
  166. }
  167. /**
  168. * ページリストを取得する(再帰)
  169. * TODO スマートフォン未対応
  170. * @param mixid $parentCategoryId / '' / 0
  171. * @return string
  172. * @access private
  173. */
  174. function __getPageListRecursive($parentCategoryId = null, $recursive = null, $level = 0) {
  175. $direct = false;
  176. $currentAgentId = $this->Page->PageCategory->getAgentId(Configure::read('BcRequest.agent'));
  177. $mobileId = $this->Page->PageCategory->getAgentId('mobile');
  178. $smartphoneId = $this->Page->PageCategory->getAgentId('smartphone');
  179. if($parentCategoryId === 0) {
  180. $direct = true;
  181. $parentCategoryId = null;
  182. }elseif(!$parentCategoryId && Configure::read('BcRequest.agent') == Configure::read('BcAgent.mobile.prefix')) {
  183. $parentCategoryId = $currentAgentId;
  184. }
  185. // ページリスト取得
  186. $conditions = array('Page.page_category_id' => $parentCategoryId);
  187. $conditions = am($conditions, $this->Page->getConditionAllowPublish());
  188. $pages = $this->Page->find('all', array(
  189. 'conditions'=> $conditions,
  190. 'fields' => array('name', 'title', 'url'),
  191. 'order' => 'Page.sort',
  192. 'recursive' => -1,
  193. 'cache' => false
  194. ));
  195. foreach($pages as $key => $page) {
  196. $pages[$key]['Page']['url'] = preg_replace('/^\/mobile/', '/m', $page['Page']['url']);
  197. $pages[$key]['Page']['url'] = preg_replace('/^\/smartphone/', '/s', $page['Page']['url']);
  198. }
  199. if(!$direct) {
  200. // カテゴリリスト取得
  201. $conditions = array('PageCategory.parent_id' => $parentCategoryId);
  202. if(!$parentCategoryId) {
  203. $conditions = am($conditions, array(array('PageCategory.id <>' => $mobileId), array('PageCategory.id <>' => $smartphoneId)));
  204. } elseif($parentCategoryId == $mobileId) {
  205. $conditions = am($conditions, array(array('PageCategory.id <>' => ''), array('PageCategory.id <>' => $smartphoneId)));
  206. } elseif($parentCategoryId == $smartphoneId) {
  207. $conditions = am($conditions, array(array('PageCategory.id <>' => ''), array('PageCategory.id <>' => $mobileId)));
  208. }
  209. $pageCategories = $this->Page->PageCategory->find('all', array(
  210. 'conditions' => $conditions,
  211. 'fields' => array('id', 'title'),
  212. 'order' => 'PageCategory.lft',
  213. 'recursive' => -1
  214. ));
  215. } else {
  216. $pageCategories = array();
  217. }
  218. // カテゴリごとの子カテゴリ取得
  219. $children = array();
  220. if($pageCategories) {
  221. $level++;
  222. foreach ($pageCategories as $key => $pageCategory) {
  223. $children = $this->__getPageListRecursive($pageCategory['PageCategory']['id'], $recursive, $level);
  224. if($children && (is_null($recursive) || $recursive > $level)) {
  225. $pageCategories[$key]['children'] = $children;
  226. }
  227. if(isset($children['pages'])) {
  228. $paths = Set::extract('/Page/name', $children['pages']);
  229. if(in_array('index', $paths)) {
  230. $cats = $this->Page->PageCategory->getPath($pageCategory['PageCategory']['id'], array('name'), -1);
  231. $cats = Set::extract('/PageCategory/name', $cats);
  232. if($cats) {
  233. $parentCategoryPath = '/'.implode('/', $cats).'/';
  234. } else {
  235. $parentCategoryPath = '/';
  236. }
  237. $parentCategoryPath = preg_replace('/^\/mobile/', '/m', $parentCategoryPath);
  238. $pageCategories[$key]['PageCategory']['url'] = $parentCategoryPath.'index';
  239. }
  240. }
  241. }
  242. }
  243. $result = array();
  244. if($pages) {
  245. $result['pages'] = $pages;
  246. }
  247. if($pageCategories) {
  248. $result['pageCategories'] = $pageCategories;
  249. }
  250. return $result;
  251. }
  252. /**
  253. * [ADMIN] 検索インデックス
  254. *
  255. * @return void
  256. * @access public
  257. */
  258. function admin_index() {
  259. $this->pageTitle = '検索インデックス コンテンツ一覧';
  260. /* 画面情報設定 */
  261. $default = array('named' => array('num' => $this->siteConfigs['admin_list_num']));
  262. $this->setViewConditions('Content', array('default' => $default));
  263. $conditions = $this->_createAdminIndexConditions($this->data);
  264. $this->paginate = array(
  265. 'conditions' => $conditions,
  266. 'fields' => array(),
  267. 'order' =>'Content.priority DESC, Content.modified DESC, Content.id',
  268. 'limit' => $this->passedArgs['num']
  269. );
  270. $this->set('datas', $this->paginate('Content'));
  271. if($this->RequestHandler->isAjax() || !empty($this->params['url']['ajax'])) {
  272. $this->render('ajax_index');
  273. return;
  274. }
  275. $this->search = 'contents_index';
  276. $this->help = 'contents_index';
  277. }
  278. /**
  279. * [ADMIN] 検索インデックス登録
  280. *
  281. * @return void
  282. * @access public
  283. */
  284. function admin_add() {
  285. $this->pageTitle = '検索インデックス コンテンツ登録';
  286. if($this->data) {
  287. $url = $this->data['Content']['url'];
  288. $url = str_replace(FULL_BASE_URL.$this->base, '', $url);
  289. if(!$this->Content->find('count', array('conditions' => array('Content.url' => $url)))) {
  290. // ルーティングのデフォルト設定を再読み込み(requestActionでルーティング設定がダブって登録されてしまう為)
  291. Router::reload();
  292. // URLのデータを取得
  293. $content = $this->requestAction($url, array('return' => 1));
  294. $View =& ClassRegistry::getObject('View');
  295. // requestActionでインスタンス化されたViewを削除
  296. // (管理システムではなく公開ページのView情報になっている可能性がある為)
  297. ClassRegistry::removeObject('View');
  298. // ルーティングのデフォルト設定を再読み込み(元の設定に復元する為)
  299. Router::reload();
  300. // 元の設定を復元
  301. Router::setRequestInfo(array($this->params, array('base' => $this->base, 'webroot' => $this->webroot)));
  302. $title = '';
  303. if(!is_a($content, 'ErrorHandler')) {
  304. $content = preg_replace('/<!-- BaserPageTagBegin -->.*?<!-- BaserPageTagEnd -->/is', '', $content);
  305. $title = $View->pageTitle;
  306. } elseif (preg_match('/\.html/', $url)) {
  307. App::import('Core', 'HttpSocket');
  308. $socket = new HttpSocket();
  309. // ※ Router::url() では、スマートURLオフの場合、/app/webroot/ 内のURLが正常に取得できない
  310. $content = $socket->get(siteUrl().$url);
  311. $code = $socket->response['status']['code'];
  312. if($code != 200) {
  313. unset($content);
  314. } else {
  315. if(preg_match('/<title>([^<]+)<\/title>/', $content, $matches)) {
  316. $title = $matches[1];
  317. $content = preg_replace('/<title>[^<]+<\/title>/', '', $content);
  318. }
  319. }
  320. } else {
  321. unset($content);
  322. }
  323. if(isset($content)) {
  324. $content = Sanitize::stripAll($content);
  325. $content = strip_tags($content);
  326. $data = array('Content' => array(
  327. 'title' => $title,
  328. 'detail' => $content,
  329. 'url' => $url,
  330. 'type' => 'その他',
  331. 'status' => true,
  332. 'priority' => 0.5
  333. ));
  334. $this->Content->create($data);
  335. if($this->Content->save()) {
  336. $this->Session->setFlash('検索インデックスに '.$url.' を追加しました。');
  337. $this->redirect(array('action' => 'index'));
  338. } else {
  339. $this->Session->setFlash('保存中にエラーが発生しました。');
  340. }
  341. } else {
  342. $this->Content->invalidate('url', '入力したURLは存在しないか、検索インデックスに登録できるURLではありません。');
  343. $this->Session->setFlash('保存中にエラーが発生しました。');
  344. }
  345. } else {
  346. $this->Content->invalidate('url', '既に登録済のURLです。');
  347. $this->Session->setFlash('入力エラーです。内容を修正してください。');
  348. }
  349. }
  350. $this->help = 'contents_add';
  351. }
  352. /**
  353. * [ADMIN] 検索インデックス削除 (ajax)
  354. *
  355. * @param int $id
  356. * @return void
  357. * @access public
  358. */
  359. function admin_ajax_delete($id = null) {
  360. if(!$id) {
  361. $this->ajaxError(500, '無効な処理です。');
  362. }
  363. /* 削除処理 */
  364. if($this->Content->del($id)) {
  365. $message = '検索インデックスより NO.'.$id.' を削除しました。';
  366. $this->Content->saveDbLog($message);
  367. exit(true);
  368. }
  369. exit();
  370. }
  371. /**
  372. * [ADMIN] 検索インデックス削除
  373. *
  374. * @param int $id
  375. * @return void
  376. * @access public
  377. */
  378. function admin_delete($id = null) {
  379. if(!$id) {
  380. $this->Session->setFlash('無効なIDです。');
  381. $this->redirect(array('action' => 'index'));
  382. }
  383. /* 削除処理 */
  384. if($this->Content->del($id)) {
  385. $message = '検索インデックスより NO.'.$id.' を削除しました。';
  386. $this->Session->setFlash($message);
  387. $this->Content->saveDbLog($message);
  388. }else {
  389. $this->Session->setFlash('データベース処理中にエラーが発生しました。');
  390. }
  391. $this->redirect(array('action' => 'index'));
  392. }
  393. /**
  394. * [ADMIN] 検索インデックス一括削除
  395. *
  396. * @param int $id
  397. * @return void
  398. * @access public
  399. */
  400. function _batch_del($ids) {
  401. if($ids){
  402. foreach($ids as $id) {
  403. /* 削除処理 */
  404. if($this->Content->del($id)) {
  405. $message = '検索インデックスより NO.'.$id.' を削除しました。';
  406. $this->Content->saveDbLog($message);
  407. }
  408. }
  409. }
  410. return true;
  411. }
  412. /**
  413. * [AJAX] 優先順位を変更する
  414. *
  415. * @return boolean
  416. * @access public
  417. */
  418. function admin_ajax_change_priority() {
  419. if($this->data) {
  420. $this->Content->set($this->data);
  421. if($this->Content->save()) {
  422. echo true;
  423. }
  424. }
  425. exit();
  426. }
  427. /**
  428. * 管理画面ページ一覧の検索条件を取得する
  429. *
  430. * @param array $data
  431. * @return string
  432. * @access protected
  433. */
  434. function _createAdminIndexConditions($data){
  435. if(empty($data['Content'])) {
  436. return array();
  437. }
  438. /* 条件を生成 */
  439. $conditions = array();
  440. $type = $data['Content']['type'];
  441. $category = $data['Content']['category'];
  442. $status = $data['Content']['status'];
  443. $keyword = $data['Content']['keyword'];
  444. unset($data['Content']['type']);
  445. unset($data['Content']['category']);
  446. unset($data['Content']['status']);
  447. unset($data['Content']['keyword']);
  448. unset($data['Content']['open']);
  449. if(!$data['Content']['priority']) {
  450. unset($data['Content']['priority']);
  451. }
  452. foreach($data['Content'] as $key => $value) {
  453. if(preg_match('/priority_[0-9]+$/', $key)) {
  454. unset($data['Content'][$key]);
  455. }
  456. }
  457. if($data['Content']) {
  458. $conditions = $this->postConditions($data);
  459. }
  460. if($type) {
  461. $conditions['Content.type'] = $type;
  462. }
  463. if($category) {
  464. if($category == 'none') {
  465. $conditions['Content.category'] = '';
  466. } else {
  467. $conditions['Content.category'] = $category;
  468. }
  469. }
  470. if($status != '') {
  471. $conditions['Content.status'] = $status;
  472. }
  473. if($keyword) {
  474. $conditions['and']['or'] = array(
  475. 'Content.title LIKE' => '%'.$keyword.'%',
  476. 'Content.detail LIKE' => '%'.$keyword.'%'
  477. );
  478. }
  479. return $conditions;
  480. }
  481. }
  482. ?>