wCMF  3.6
 All Classes Namespaces Files Functions Variables Groups Pages
class.ConfigController.php
Go to the documentation of this file.
1 <?php
2 /**
3  * wCMF - wemove Content Management Framework
4  * Copyright (C) 2005-2014 wemove digital solutions GmbH
5  *
6  * Licensed under the terms of any of the following licenses
7  * at your choice:
8  *
9  * - GNU Lesser General Public License (LGPL)
10  * http://www.gnu.org/licenses/lgpl.html
11  * - Eclipse Public License (EPL)
12  * http://www.eclipse.org/org/documents/epl-v10.php
13  *
14  * See the license.txt file distributed with this work for
15  * additional information.
16  *
17  * $Id: class.ConfigController.php 1462 2014-02-04 23:52:27Z iherwig $
18  */
19 require_once(BASE."wcmf/lib/presentation/class.Controller.php");
20 require_once(BASE."wcmf/lib/persistence/class.PersistenceFacade.php");
21 require_once(BASE."wcmf/lib/model/class.Node.php");
22 require_once(BASE."wcmf/lib/util/class.InifileParser.php");
23 require_once(BASE."wcmf/lib/util/class.ArrayUtil.php");
24 
25 /**
26  * @class ConfigController
27  * @ingroup Controller
28  * @brief ConfigController is used to edit configuration files. The controller
29  * uses the global variable CONFIG_PATH to locate the configuration files.
30  * The global variables CONFIG_EXTENSION and MAIN_CONFIG_FILE are used to
31  * determine which files are configuration files and which one is the default
32  * one.
33  *
34  * <b>Input actions:</b>
35  * - @em newconfig Create a new configuration file
36  * - @em editconfig Edit a configuration file
37  * - @em save Save changes to the current configuration file
38  * - @em delconfig Delete a configuration file
39  * - @em newsection Create a new section in the current configuration file
40  * - @em delsection Delete a section from the current configuration file
41  * - @em newoption Create a new option in the current configuration file
42  * - @em deloption Delete an option in the current configuration file
43  *
44  * <b>Output actions:</b>
45  * - @em ok In any case
46  *
47  * @param[in,out] oid The name of the currrent configuration file
48  * @param[in] poid The name of the currrent configuration section
49  * @param[in] type_section_section_<sectionname> A list of variables defining the section names
50  * @param[in] type_option_section_<sectionname>_option_<optionname> A list of variables defining the option names
51  * @param[in] type_value_section_<sectionname>_option_<optionname> A list of variables defining the option values
52  * @param[in] deleteoids The names of the configuration files to delete (comma separated list)
53  * @param[out] configfile A reference to an InifileParser instance representing the current configuration file
54  * @param[out] ismainconfigfile True/False wether the current configuration file is the MAIN_CONFIG_FILE
55  * @param[out] configFilenameNoExtension The name of the currrent configuration file without CONFIG_EXTENSION
56  * @param[out] internallink An internal link that the view can use to position the window at the field to edit
57  *
58  * @author ingo herwig <ingo@wemove.com>
59  */
61 {
62  /**
63  * @see Controller::initialize()
64  */
65  function initialize(&$request, &$response)
66  {
67  if (strlen($request->getContext()) == 0)
68  {
69  $request->setContext('config');
70  $response->setContext('config');
71  }
72 
73  parent::initialize($request, $response);
74  }
75  /**
76  * @see Controller::validate()
77  */
78  function validate()
79  {
80  if(in_array($this->_request->getAction(), array('editconfig', 'save')))
81  {
82  if(strlen($this->_request->getValue('oid')) == 0)
83  {
84  $this->setErrorMsg("No 'oid' given in data.");
85  return false;
86  }
87  }
88  if($this->_request->getAction() == 'delconfig')
89  {
90  if(strlen($this->_request->getValue('deleteoids')) == 0)
91  {
92  $this->setErrorMsg("No 'deleteoids' given in data.");
93  return false;
94  }
95  }
96  return true;
97  }
98  /**
99  * @see Controller::hasView()
100  */
101  function hasView()
102  {
103  if ($this->_request->getAction() == 'delconfig')
104  return false;
105  else
106  return true;
107  }
108  /**
109  * Process action and assign data to View.
110  * @return Array of given context and action 'ok' on delete.
111  * False else (Stop action processing chain).
112  * @see Controller::executeKernel()
113  */
114  function executeKernel()
115  {
116  global $CONFIG_PATH, $CONFIG_EXTENSION, $MAIN_CONFIG_FILE;
117  $persistenceFacade = &PersistenceFacade::getInstance();
118  $configFilename = $this->_request->getValue('oid');
119  // strip path
120  $configFilename = str_replace($CONFIG_PATH, '', $configFilename);
121  $configFilenameNoExtension = str_replace('.'.$CONFIG_EXTENSION, '', $configFilename);
122 
123  // process actions
124 
125  // DELETE CONFIG
126  if($this->_request->getAction() == 'delconfig')
127  {
128  $deleteOIDs = split(',', $this->_request->getValue('deleteoids'));
129  foreach($deleteOIDs as $oid)
130  unlink($oid);
131 
132  // return
133  $this->_response->setAction('ok');
134  return true;
135  }
136 
137  // NEW CONFIG
138  if($this->_request->getAction() == 'newconfig')
139  {
140  $newNode = new Node('config');
141  $newConfigFilename = 'config'.md5(microtime()).'.'.$CONFIG_EXTENSION;
142  $fh = fopen($CONFIG_PATH.$newConfigFilename, 'w');
143  fclose($fh);
144  $configFilename = $newConfigFilename;
145  $configFilenameNoExtension = preg_replace('/\.'.$CONFIG_EXTENSION.'/', '', $configFilename);
146 
147  // redirect directly to edit view
148  $this->_request->setAction('editconfig');
149  }
150 
151  // EDIT, SAVE
152  $internalLink = '';
153  if (in_array($this->_request->getAction(), array('editconfig', 'save')) || in_array($this->_request->getContext(), array('config')))
154  {
155  // load model
156  $configFile = new InifileParser();
157  $configFile->parseIniFile($CONFIG_PATH.$configFilename, false);
158 
159  // save changes
160  if ($this->_request->getAction() == 'save')
161  {
162  $data = &$this->_request->getData();
163  foreach($data as $control => $value)
164  {
165  // unescape double quotes
166  $value = str_replace("\\\"", "\"", $value);
167 
168  $key = $this->getKeyFromControlName($control);
169  if ($key['type'] == 'section')
170  {
171  // rename section if section name changed
172  if ($key['section'] != $value)
173  {
174  if ($configFile->renameSection($key['section'], $value) === false)
175  $this->appendErrorMsg($configFile->getErrorMsg());
176  else
177  $this->renameControlNames($key, $value);
178  }
179  }
180  elseif ($key['type'] == 'option')
181  {
182  // rename option if option name changed
183  if ($key['option'] != $value)
184  {
185  if ($configFile->renameKey($key['option'], $value, $key['section']) === false)
186  $this->appendErrorMsg($configFile->getErrorMsg());
187  else
188  {
189  $this->renameControlNames($key, $value);
190  $internalLink = $key['section'].'_'.$value;
191  }
192  }
193  }
194  elseif ($key['type'] == 'value')
195  {
196  // set value if value changed
197  if ($configFile->getValue($key['option'], $key['section']) != $value)
198  {
199  if ($configFile->setValue($key['option'], $value, $key['section'], false) === false)
200  $this->appendErrorMsg($configFile->getErrorMsg());
201  else
202  $internalLink = $key['section'].'_'.$key['option'];
203  }
204  }
205  if ($control == 'name' && $value != $configFilenameNoExtension)
206  {
207  $newConfigFilename = $value.'.'.$CONFIG_EXTENSION;
208  if (!file_exists($CONFIG_PATH.$newConfigFilename))
209  {
210  rename($CONFIG_PATH.$configFilename, $CONFIG_PATH.$newConfigFilename);
211  $configFilename = $newConfigFilename;
212  $configFilenameNoExtension = preg_replace('/\.'.$CONFIG_EXTENSION.'/', '', $configFilename);
213  }
214  else
215  $this->appendErrorMsg(Message::get("Configuration file %1% already exists.", array($CONFIG_PATH.$newConfigFilename)));
216  }
217  }
218  }
219  // insert section
220  if($this->_request->getAction() == 'newsection')
221  {
222  $newNode = new Node('section');
223  $sectionName = substr($newNode->getOID(), 0, 20);
224  $configFile->createSection($sectionName);
225  }
226  // insert option
227  if($this->_request->getAction() == 'newoption')
228  {
229  $newNode = new Node('option');
230  $sectionName = $this->_request->getValue('poid');
231  $optionName = substr($newNode->getOID(), 0, 20);
232  $configFile->setValue($optionName, '', $sectionName);
233  $internalLink = $sectionName.'_'.$optionName;
234  }
235  // delete section
236  if($this->_request->getAction() == 'delsection')
237  {
238  $deleteOIDs = split(',', $this->_request->getValue('deleteoids'));
239  foreach($deleteOIDs as $oid)
240  {
241  $key = $this->getKeyFromControlName($oid);
242  $configFile->removeSection($key['section']);
243  }
244  }
245  // delete option
246  if($this->_request->getAction() == 'deloption')
247  {
248  $deleteOIDs = split(',', $this->_request->getValue('deleteoids'));
249  foreach($deleteOIDs as $oid)
250  {
251  $key = $this->getKeyFromControlName($oid);
252  $configFile->removeKey($key['option'], $key['section']);
253  }
254  $internalLink = $key['section'];
255  }
256  // save on changes
257  if ($configFile->isModified())
258  $configFile->writeIniFile($CONFIG_PATH.$configFilename);
259 
260  // reload model
261  $configFile = new InifileParser();
262  $configFile->parseIniFile($CONFIG_PATH.$configFilename, false);
263 
264  // assign model to view
265  $this->_response->setValue('oid', $configFilename);
266  $this->_response->setValue('configfile', $configFile);
267  $this->_response->setValue('ismainconfigfile', $MAIN_CONFIG_FILE == $configFilename);
268  $this->_response->setValue('configFilenameNoExtension', $configFilenameNoExtension);
269  $this->_response->setValue('internallink', $internalLink);
270  }
271 
272  // success
273  $this->_response->setAction('ok');
274  return false;
275  }
276  /**
277  * Extract the parameters for locating a value in a configuration file (type, section, key).
278  * @param controlname A string of the from 'type_typeName_section_sectionName_option_optionName'
279  * @return An assoziative array with the keys 'type', 'section', 'option',
280  * where type typically has one of the values 'section', 'option', 'value'
281  */
282  function getKeyFromControlName($controlname)
283  {
284  preg_match("/^type_(.+?)_section_(.+?)(_option_(.+?))*$/", $controlname, $matches);
285  return array('type' => $matches[1], 'section' => $matches[2], 'option' => $matches[4]);
286  }
287  /**
288  * Extract the parameters for locating a value in a configuration file (type, section, key).
289  * @param key An assoziative array as provided by getKeyFromControlName() describing the entry
290  * @return A string of the from 'type_typeName_section_sectionName_option_optionName'
291  */
292  function makeControlNameFromKey($key)
293  {
294  $controlName = 'type_'.$key['type'].'_section_'.$key['section'];
295  if ($key['type'] == 'option' || $key['type'] == 'value')
296  $controlName .= '_option_'.$key['option'];
297  return $controlName;
298  }
299  /**
300  * Rename all control names in $this->_request->getData().
301  * @param key An assoziative array as provided by getKeyFromControlName() describing the entry that has changed
302  * @param value The new value of the entry to construct the control name from
303  */
304  function renameControlNames($key, $value)
305  {
306  $data = &$this->_request->getData();
307  foreach(array_keys($data) as $oldControlName)
308  {
309  $oldKey = $this->getKeyFromControlName($oldControlName);
310  if ($key[$key['type']] == $oldKey[$key['type']])
311  {
312  $newKey = $oldKey;
313  $newKey[$key['type']] = $value;
314  $newControlName = $this->makeControlNameFromKey($newKey);
315  ArrayUtil::key_array_rename($data, $oldControlName, $newControlName);
316  }
317  }
318  }
319 }
320 ?>
get($message, $parameters=null, $domain='', $lang='')
Node is the basic component for building trees (although a Node can have one than more parents)...
Definition: class.Node.php:118
getKeyFromControlName($controlname)
renameControlNames($key, $value)
initialize(&$request, &$response)
key_array_rename(&$input, $oldname, $newname)
Controller is the base class of all controllers. If a Controller has a view it is expected to reside ...
InifileParser provides basic services for parsing a ini file from the file system.
ConfigController is used to edit configuration files. The controller uses the global variable CONFIG_...