PageRenderTime 53ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/baser/controllers/plugins_controller.php

https://github.com/hashing/basercms
PHP | 478 lines | 266 code | 52 blank | 160 comment | 50 complexity | 9e57a429df7c342c24913419810309b3 MD5 | raw file
Possible License(s): MIT
  1. <?php
  2. /* SVN FILE: $Id$ */
  3. /**
  4. * Plugin 拡張クラス
  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. * Plugin 拡張クラス
  22. * プラグインのコントローラーより継承して利用する
  23. *
  24. * @package baser.controllers
  25. */
  26. class PluginsController extends AppController {
  27. /**
  28. * クラス名
  29. *
  30. * @var string
  31. * @access public
  32. */
  33. var $name = 'Plugins';
  34. /**
  35. * モデル
  36. *
  37. * @var array
  38. * @access public
  39. */
  40. var $uses = array('GlobalMenu','Plugin','PluginContent');
  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_TIME_HELPER, BC_FORM_HELPER);
  55. /**
  56. * サブメニューエレメント
  57. *
  58. * @var array
  59. * @access public
  60. */
  61. var $subMenuElements = array();
  62. /**
  63. * ぱんくずナビ
  64. *
  65. * @var array
  66. * @access public
  67. */
  68. var $crumbs = array(
  69. array('name' => 'プラグイン管理', 'url' => array('controller' => 'plugins', 'action' => 'index'))
  70. );
  71. /**
  72. * コンテンツID
  73. *
  74. * @var int
  75. */
  76. var $contentId = null;
  77. /**
  78. * beforeFilter
  79. *
  80. * @return void
  81. * @access private
  82. */
  83. function beforeFilter() {
  84. parent::beforeFilter();
  85. if(!isset($this->Plugin)) {
  86. $this->cakeError('missingClass', array(array('className' => 'Plugin',
  87. 'notice'=>'プラグインでは、コントローラーで、Pluginモデルを読み込んでおく必要があります。usesプロパティを確認してください。')));
  88. }
  89. // 有効でないプラグインを実行させない
  90. if($this->name != 'Plugins' && !$this->Plugin->find('all',array('conditions'=>array('name'=>$this->params['plugin'], 'status'=>true)))) {
  91. $this->notFound();
  92. }
  93. $this->contentId = $this->getContentId();
  94. }
  95. /**
  96. * コンテンツIDを取得する
  97. * 一つのプラグインで複数のコンテンツを実装する際に利用する。
  98. *
  99. * @return int $pluginNo
  100. * @access public
  101. */
  102. function getContentId() {
  103. // 管理画面の場合には取得しない
  104. if(!empty($this->params['admin'])){
  105. return null;
  106. }
  107. if(!isset($this->PluginContent)) {
  108. return null;
  109. }
  110. if(!isset($this->params['url']['url'])) {
  111. return null;
  112. }
  113. $contentName = '';
  114. $url = preg_replace('/^\//', '', $this->params['url']['url']);
  115. $url = split('/', $url);
  116. if($url[0]!=Configure::read('BcRequest.agentAlias')) {
  117. if(!empty($this->params['prefix']) && $url[0] == $this->params['prefix']) {
  118. if(isset($url[1])) {
  119. $contentName = $url[1];
  120. }
  121. }else {
  122. $contentName = $url[0];
  123. }
  124. }else {
  125. if(!empty($this->params['prefix']) && $url[0] == $this->params['prefix']) {
  126. $contentName = $url[2];
  127. }else {
  128. $contentName = $url[1];
  129. }
  130. }
  131. // プラグインと同じ名前のコンテンツ名の場合に正常に動作しないので
  132. // とりあえずコメントアウト
  133. /*if( Inflector::camelize($url) == $this->name){
  134. return null;
  135. }*/
  136. $pluginContent = $this->PluginContent->findByName($contentName);
  137. if($pluginContent) {
  138. return $pluginContent['PluginContent']['content_id'];
  139. }else {
  140. return null;
  141. }
  142. }
  143. /**
  144. * プラグインの一覧を表示する
  145. *
  146. * @return void
  147. * @access public
  148. */
  149. function admin_index() {
  150. $datas = $this->Plugin->find('all');
  151. if(!$datas) {
  152. $datas = array();
  153. }
  154. // プラグインフォルダーのチェックを行う。
  155. // データベースに登録されていないプラグインをリストアップ
  156. $pluginFolder = new Folder(APP.'plugins'.DS);
  157. $plugins = $pluginFolder->read(true,true);
  158. $unRegistereds = array();
  159. $registereds = array();
  160. foreach($plugins[0] as $plugin) {
  161. $exists = false;
  162. $pluginData = array();
  163. foreach($datas as $data) {
  164. if($plugin == $data['Plugin']['name']) {
  165. $pluginData = $data;
  166. $exists = true;
  167. break;
  168. }
  169. }
  170. // プラグインのバージョンを取得
  171. $version = $this->getBaserVersion($plugin);
  172. // 設定ファイル読み込み
  173. $title = $description = $author = $url = $adminLink = '';
  174. $appConfigPath = APP.DS.'plugins'.DS.$plugin.DS.'config'.DS.'config.php';
  175. $baserConfigPath = BASER_PLUGINS.$plugin.DS.'config'.DS.'config.php';
  176. if(file_exists($appConfigPath)) {
  177. include $appConfigPath;
  178. }elseif(file_exists($baserConfigPath)) {
  179. include $baserConfigPath;
  180. }
  181. if(isset($title))
  182. $pluginData['Plugin']['title'] = $title;
  183. if(isset($description))
  184. $pluginData['Plugin']['description'] = $description;
  185. if(isset($author))
  186. $pluginData['Plugin']['author'] = $author;
  187. if(isset($url))
  188. $pluginData['Plugin']['url'] = $url;
  189. $pluginData['Plugin']['update'] = false;
  190. $pluginData['Plugin']['old_version'] = false;
  191. if($exists) {
  192. if(isset($adminLink))
  193. $pluginData['Plugin']['admin_link'] = $adminLink;
  194. // バージョンにBaserから始まるプラグイン名が入っている場合は古いバージョン
  195. if(!$pluginData['Plugin']['version'] && preg_match('/^Baser[a-zA-Z]+\s([0-9\.]+)$/', $version, $matches)) {
  196. $pluginData['Plugin']['version'] = $matches[1];
  197. $pluginData['Plugin']['old_version'] = true;
  198. }elseif(verpoint ($pluginData['Plugin']['version']) < verpoint($version) && !in_array($pluginData['Plugin']['name'],array('blog', 'feed', 'mail'))) {
  199. $pluginData['Plugin']['update'] = true;
  200. }
  201. $registereds[] = $pluginData;
  202. } else {
  203. // バージョンにBaserから始まるプラグイン名が入っている場合は古いバージョン
  204. if(preg_match('/^Baser[a-zA-Z]+\s([0-9\.]+)$/', $version,$matches)) {
  205. $version = $matches[1];
  206. $pluginData['Plugin']['old_version'] = true;
  207. }
  208. $pluginData['Plugin']['id'] = '';
  209. $pluginData['Plugin']['name'] = $plugin;
  210. $pluginData['Plugin']['created'] = '';
  211. $pluginData['Plugin']['version'] = $version;
  212. $pluginData['Plugin']['status'] = false;
  213. $pluginData['Plugin']['modified'] = '';
  214. $pluginData['Plugin']['admin_link'] = '';
  215. $unRegistereds[] = $pluginData;
  216. }
  217. }
  218. $datas = array_merge($registereds,$unRegistereds);
  219. // 表示設定
  220. $this->set('datas',$datas);
  221. $this->subMenuElements = array('plugins');
  222. $this->pageTitle = 'プラグイン一覧';
  223. $this->help = 'plugins_index';
  224. }
  225. /**
  226. * [ADMIN] ファイル削除
  227. *
  228. * @param string プライグイン名
  229. * @return void
  230. * @access public
  231. * @deprecated admin_ajax_delete_file に移行
  232. */
  233. function admin_delete_file($pluginName) {
  234. $this->__deletePluginFile($pluginName);
  235. $message = 'プラグイン「'.$pluginName.'」 を完全に削除しました。';
  236. $this->Session->setFlash($message);
  237. $this->redirect(array('action' => 'index'));
  238. }
  239. /**
  240. * [ADMIN] ファイル削除
  241. *
  242. * @param string プライグイン名
  243. * @return void
  244. * @access public
  245. */
  246. function admin_ajax_delete_file($pluginName) {
  247. if($pluginName) {
  248. $this->ajaxError(500, '無効な処理です。');
  249. }
  250. $pluginName = urldecode($pluginName);
  251. $this->__deletePluginFile($pluginName);
  252. $this->Plugin->saveDbLog('プラグイン「'.$pluginName.'」 を完全に削除しました。');
  253. exit(true);
  254. }
  255. /**
  256. * プラグインファイルを削除する
  257. *
  258. * @param string $pluginName
  259. * @return void
  260. * @access private
  261. */
  262. function __deletePluginFile($pluginName) {
  263. $appPath = APP.'plugins'.DS.$pluginName.DS.'config'.DS.'sql'.DS;
  264. $baserPath = BASER_PLUGINS.$pluginName.DS.'config'.DS.'sql'.DS;
  265. $tmpPath = TMP.'schemas'.DS.'uninstall'.DS;
  266. $folder = new Folder();
  267. $folder->delete($tmpPath);
  268. $folder->create($tmpPath);
  269. if(is_dir($appPath)) {
  270. $path = $appPath;
  271. }else {
  272. $path = $baserPath;
  273. }
  274. // インストール用スキーマをdropスキーマとして一時フォルダに移動
  275. $folder = new Folder($path);
  276. $files = $folder->read(true, true);
  277. if(is_array($files[1])) {
  278. foreach($files[1] as $file) {
  279. if(preg_match('/\.php$/', $file)) {
  280. $from = $path.DS.$file;
  281. $to = $tmpPath.'drop_'.$file;
  282. copy($from, $to);
  283. chmod($to, 0666);
  284. }
  285. }
  286. }
  287. // テーブルを削除
  288. $this->Plugin->loadSchema('plugin', $tmpPath);
  289. // プラグインフォルダを削除
  290. $folder->delete(APP.'plugins'.DS.$pluginName);
  291. // 一時フォルダを削除
  292. $folder->delete($tmpPath);
  293. }
  294. /**
  295. * [ADMIN] 登録処理
  296. *
  297. * @param string $name
  298. * @return void
  299. * @access public
  300. */
  301. function admin_add($name) {
  302. $name = urldecode($name);
  303. if(!$this->data) {
  304. if(file_exists(APP.'plugins'.DS.$name.DS.'config'.DS.'config.php')) {
  305. include APP.'plugins'.DS.$name.DS.'config'.DS.'config.php';
  306. }elseif(file_exists(BASER_PLUGINS.$name.DS.'config'.DS.'config.php')) {
  307. include BASER_PLUGINS.$name.DS.'config'.DS.'config.php';
  308. }
  309. $this->data['Plugin']['name']=$name;
  310. if(isset($title)) {
  311. $this->data['Plugin']['title'] = $title;
  312. } else {
  313. $this->data['Plugin']['title'] = $name;
  314. }
  315. $this->data['Plugin']['status'] = true;
  316. $this->data['Plugin']['version'] = $this->getBaserVersion($name);
  317. if(!empty($installMessage)) {
  318. $this->Session->setFlash($installMessage);
  319. }
  320. }else {
  321. $data = $this->Plugin->find('first',array('conditions'=>array('name'=>$this->data['Plugin']['name'])));
  322. if($data) {
  323. // 既にインストールデータが存在する場合は、DBのバージョンは変更しない
  324. $data['Plugin']['name']=$this->data['Plugin']['name'];
  325. $data['Plugin']['title']=$this->data['Plugin']['title'];
  326. $data['Plugin']['status']=$this->data['Plugin']['status'];
  327. $this->Plugin->set($data);
  328. } else {
  329. if(file_exists(APP.'plugins'.DS.$name.DS.'config'.DS.'init.php')) {
  330. include APP.'plugins'.DS.$name.DS.'config'.DS.'init.php';
  331. }elseif(file_exists(BASER_PLUGINS.$name.DS.'config'.DS.'init.php')) {
  332. include BASER_PLUGINS.$name.DS.'config'.DS.'init.php';
  333. }
  334. $data = $this->data;
  335. $this->Plugin->create($data);
  336. }
  337. // データを保存
  338. if($this->Plugin->save()) {
  339. clearAllCache();
  340. $message = '新規プラグイン「'.$data['Plugin']['name'].'」を baserCMS に登録しました。';
  341. $this->Session->setFlash($message);
  342. $this->Plugin->saveDbLog($message);
  343. $this->redirect(array('action' => 'index'));
  344. }else {
  345. $this->Session->setFlash('プラグインに問題がある為インストールを完了できません。開発者に確認してください。');
  346. }
  347. }
  348. /* 表示設定 */
  349. $this->subMenuElements = array('plugins');
  350. $this->pageTitle = '新規プラグイン登録';
  351. $this->help = 'plugins_form';
  352. $this->render('form');
  353. }
  354. /**
  355. * [ADMIN] 削除処理
  356. *
  357. * @param int ID
  358. * @return void
  359. * @access public
  360. * @deprecated admin_ajax_delete に移行
  361. */
  362. function admin_delete($id = null) {
  363. /* 除外処理 */
  364. if(!$id) {
  365. $this->Session->setFlash('無効なIDです。');
  366. $this->redirect(array('action' => 'index'));
  367. }
  368. $data = $this->Plugin->read(null, $id);
  369. $data['Plugin']['status'] = false;
  370. /* 削除処理 */
  371. if($this->Plugin->save($data)) {
  372. clearAllCache();
  373. $message = 'プラグイン「'.$data['Plugin']['title'].'」 を 無効化しました。';
  374. $this->Session->setFlash($message);
  375. $this->Plugin->saveDbLog($message);
  376. }else {
  377. $this->Session->setFlash('データベース処理中にエラーが発生しました。');
  378. }
  379. $this->redirect(array('action' => 'index'));
  380. }
  381. /**
  382. * [ADMIN] 削除処理 (ajax)
  383. *
  384. * @param int ID
  385. * @return void
  386. * @access public
  387. */
  388. function admin_ajax_delete($id = null) {
  389. /* 除外処理 */
  390. if(!$id) {
  391. $this->ajaxError(500, '無効な処理です。');
  392. }
  393. $data = $this->Plugin->read(null, $id);
  394. $data['Plugin']['status'] = false;
  395. $this->Plugin->set($data);
  396. /* 削除処理 */
  397. if($this->Plugin->save()) {
  398. clearAllCache();
  399. $this->Plugin->saveDbLog('プラグイン「'.$data['Plugin']['title'].'」 を 無効化しました。');
  400. exit(true);
  401. }
  402. exit();
  403. }
  404. /**
  405. * 一括無効
  406. *
  407. * @param array $ids
  408. * @return boolean
  409. * @access protected
  410. */
  411. function _batch_del($ids) {
  412. if($ids) {
  413. foreach($ids as $id) {
  414. $data = $this->Plugin->read(null, $id);
  415. $data['Plugin']['status'] = false;
  416. $this->Plugin->set($data);
  417. if($this->Plugin->save()) {
  418. $this->Plugin->saveDbLog('プラグイン「'.$data['Plugin']['title'].'」 を 無効化しました。');
  419. }
  420. }
  421. clearAllCache();
  422. }
  423. return true;
  424. }
  425. }
  426. ?>