Standardize @inheritDoc annotation
[civicrm-core.git] / CRM / Admin / Page / CKEditorConfig.php
CommitLineData
7266e09b
CW
1<?php
2/*
3 +--------------------------------------------------------------------+
7e9e8871 4 | CiviCRM version 4.7 |
7266e09b
CW
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2015 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
26 */
27
28/**
29 *
30 * @package CRM
31 * @copyright CiviCRM LLC (c) 2004-2015
7266e09b
CW
32 */
33
34/**
ce064e4f 35 * Page for configuring CKEditor options.
7266e09b
CW
36 *
37 * Note that while this is implemented as a CRM_Core_Page, it is actually a form.
47b59d65 38 * Because the form needs to be submitted and refreshed via javascript, it seemed like
7266e09b
CW
39 * Quickform and CRM_Core_Form/Controller might get in the way.
40 */
41class CRM_Admin_Page_CKEditorConfig extends CRM_Core_Page {
42
47b59d65 43 const CONFIG_FILENAME = '[civicrm.files]/persist/crm-ckeditor-config.js';
7266e09b
CW
44
45 /**
46 * Default settings if config file has not been initialized
47 *
48 * @var array
49 */
50 public $defaultSettings = array(
51 'skin' => 'moono',
52 'extraPlugins' => '',
53 );
54
55 /**
ce064e4f 56 * Run page.
57 *
7266e09b
CW
58 * @return string
59 */
60 public function run() {
61 // If the form was submitted, take appropriate action.
62 if (!empty($_POST['revert'])) {
63 self::deleteConfigFile();
64 }
65 elseif (!empty($_POST['config'])) {
66 $this->save($_POST);
67 }
68
69 CRM_Core_Resources::singleton()
80ab9d76 70 ->addScriptFile('civicrm', 'bower_components/ckeditor/ckeditor.js', 0, 'html-header')
7266e09b
CW
71 ->addScriptFile('civicrm', 'bower_components/ckeditor/samples/toolbarconfigurator/js/fulltoolbareditor.js', 1)
72 ->addScriptFile('civicrm', 'bower_components/ckeditor/samples/toolbarconfigurator/js/abstracttoolbarmodifier.js', 2)
73 ->addScriptFile('civicrm', 'bower_components/ckeditor/samples/toolbarconfigurator/js/toolbarmodifier.js', 3)
74 ->addScriptFile('civicrm', 'js/wysiwyg/admin.ckeditor-configurator.js', 10)
75 ->addStyleFile('civicrm', 'bower_components/ckeditor/samples/toolbarconfigurator/css/fontello.css')
76 ->addStyleFile('civicrm', 'bower_components/ckeditor/samples/css/samples.css')
77 ->addVars('ckConfig', array(
78 'plugins' => array_values($this->getCKPlugins()),
79 ));
80
81 $this->assign('skins', $this->getCKSkins());
82 $this->assign('skin', $this->getConfigSetting('skin'));
83 $this->assign('extraPlugins', $this->getConfigSetting('extraPlugins'));
84 $this->assign('configUrl', self::getConfigUrl());
85 $this->assign('revertConfirm', htmlspecialchars(ts('Are you sure you want to revert all changes?', array('escape' => 'js'))));
86
87 CRM_Utils_System::appendBreadCrumb(array(array(
88 'url' => CRM_Utils_System::url('civicrm/admin/setting/preferences/display', 'reset=1'),
89 'title' => ts('Display Preferences'),
90 )));
91
92 return parent::run();
93 }
94
95 /**
96 * Generate the config js file based on posted data.
97 *
98 * @param array $params
99 */
100 public function save($params) {
101 $config = "/**\n"
102 . " * CKEditor config file auto-generated by CiviCRM.\n"
103 . " *\n"
104 . " * Note: This file will be overwritten if settings are modified at:\n"
105 . " * @link " . CRM_Utils_System::url(CRM_Utils_System::currentPath(), NULL, TRUE, NULL, FALSE) . "\n"
106 . " */\n\n"
107 // Standardize line-endings
108 . preg_replace('~\R~u', "\n", $params['config']);
109
110 // Use defaultSettings as a whitelist so we don't just insert any old junk into the file
111 foreach ($this->defaultSettings as $key => $default) {
112 if (isset($params[$key]) && strlen($params[$key])) {
113 $pos = strrpos($config, '};');
114 $setting = "\n\tconfig.$key = '{$params[$key]}';\n";
115 $config = substr_replace($config, $setting, $pos, 0);
116 }
117 }
118 self::saveConfigFile($config);
119 if (!empty($params['save'])) {
120 CRM_Core_Session::setStatus(ts("You may need to clear your browser's cache to see the changes in CiviCRM."), ts('CKEditor Saved'), 'success');
121 }
122 }
123
124 /**
47b59d65 125 * Get available CKEditor plugin list.
ce064e4f 126 *
7266e09b
CW
127 * @return array
128 */
129 private function getCKPlugins() {
130 $plugins = array();
47b59d65 131 $pluginDir = Civi::paths()->getPath('[civicrm.root]/bower_components/ckeditor/plugins');
7266e09b
CW
132
133 foreach (glob($pluginDir . '/*', GLOB_ONLYDIR) as $dir) {
134 $dir = rtrim(str_replace('\\', '/', $dir), '/');
135 $name = substr($dir, strrpos($dir, '/') + 1);
136 $dir = CRM_Utils_file::addTrailingSlash($dir, '/');
137 if (is_file($dir . 'plugin.js')) {
138 $plugins[$name] = array(
139 'id' => $name,
140 'text' => ucfirst($name),
141 'icon' => NULL,
142 );
143 if (is_dir($dir . "icons")) {
144 if (is_file($dir . "icons/$name.png")) {
145 $plugins[$name]['icon'] = "bower_components/ckeditor/plugins/$name/icons/$name.png";
146 }
147 elseif (glob($dir . "icons/*.png")) {
148 $icon = CRM_Utils_Array::first(glob($dir . "icons/*.png"));
149 $icon = rtrim(str_replace('\\', '/', $icon), '/');
150 $plugins[$name]['icon'] = "bower_components/ckeditor/plugins/$name/icons/" . substr($icon, strrpos($icon, '/') + 1);
151 }
152 }
153 }
154 }
155
156 return $plugins;
157 }
158
159 /**
47b59d65 160 * Get available CKEditor skins.
ce064e4f 161 *
7266e09b
CW
162 * @return array
163 */
164 private function getCKSkins() {
165 $skins = array();
47b59d65 166 $skinDir = Civi::paths()->getPath('[civicrm.root]/bower_components/ckeditor/skins');
7266e09b
CW
167 foreach (glob($skinDir . '/*', GLOB_ONLYDIR) as $dir) {
168 $dir = rtrim(str_replace('\\', '/', $dir), '/');
169 $skins[] = substr($dir, strrpos($dir, '/') + 1);
170 }
171 return $skins;
172 }
173
174 /**
175 * @param $setting
176 * @return string
177 */
178 private function getConfigSetting($setting) {
179 $value = CRM_Utils_Array::value($setting, $this->defaultSettings, '');
180 $file = self::getConfigFile();
181 if ($file) {
182 $contents = file_get_contents($file);
183 $matches = array();
184 preg_match("/\sconfig\.$setting\s?=\s?'([^']*)'/", $contents, $matches);
185 if ($matches) {
186 $value = $matches[1];
187 }
188 }
189 return $value;
190 }
191
192 /**
193 * @return null|string
194 */
195 public static function getConfigUrl() {
196 if (self::getConfigFile()) {
80ab9d76 197 return Civi::paths()->getUrl(self::CONFIG_FILENAME, 'absolute');
7266e09b
CW
198 }
199 return NULL;
200 }
201
202 /**
203 * @param bool $checkIfFileExists
204 * If false, this fn will return fileName even if it doesn't exist
205 *
206 * @return null|string
207 */
208 public static function getConfigFile($checkIfFileExists = TRUE) {
47b59d65 209 $fileName = Civi::paths()->getPath(self::CONFIG_FILENAME);
7266e09b
CW
210 return !$checkIfFileExists || is_file($fileName) ? $fileName : NULL;
211 }
212
213 /**
214 * @param string $contents
215 */
216 public static function saveConfigFile($contents) {
217 $file = self::getConfigFile(FALSE);
218 file_put_contents($file, $contents);
219 }
220
221 /**
ce064e4f 222 * Delete config file.
7266e09b
CW
223 */
224 public static function deleteConfigFile() {
225 $file = self::getConfigFile();
226 if ($file) {
227 unlink($file);
228 }
229 }
230
231}