<?xml version="1.0" encoding="UTF-8" ?><rss version="2.0"><channel><title>BEdita Documents and Resources | Core</title><link>http://docs3.bedita.net/core</link><description>Architecture &amp; CMS</description><language>eng</language><item><title>Event System and Callbacks</title><description>&lt;hr/&gt;&lt;p&gt;Since &lt;strong&gt;version 3.6.0&lt;/strong&gt; BEdita is shipped with a basic event system, along with a callback manager that enables the binding of model events simply plugging callback behaviors, without the need to edit the model configuration itself, hence leaving core code intact.&lt;/p&gt;

&lt;h1 id=&quot;toc_0&quot;&gt;Automatic callback behaviors&lt;/h1&gt;

&lt;p&gt;By giving a special name to your behaviors, you can attach listeners to some built-in CakePHP&#039;s model events without editing the core code. Such callback system is handled by the &lt;code&gt;CallbackBehavior&lt;/code&gt; which is automatically attached to every &lt;code&gt;BEObject&lt;/code&gt; in &quot;callback manager&quot; mode.&lt;/p&gt;

&lt;h2 id=&quot;toc_1&quot;&gt;&lt;code&gt;CallbackBehavior&lt;/code&gt; configuration&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;CallbackBehavior&lt;/code&gt; has an optional setting &lt;code&gt;callbackManager&lt;/code&gt; that allows you to decide if you want to attach your behaviors&#039; methods as listeners for events handled by &lt;code&gt;BeCallbackManager&lt;/code&gt; (see below for detailed documentation) or you prefer to use standard CakePHP behaviors system. By default, &lt;code&gt;BeCallbackManager&lt;/code&gt; will be used.&lt;/p&gt;

&lt;h2 id=&quot;toc_2&quot;&gt;Adding custom callbacks&lt;/h2&gt;

&lt;p&gt;Let&#039;s say you need to execute a custom piece of code every time an &lt;code&gt;Event&lt;/code&gt; is saved. Normally, you would create a behavior and then add the newly-born behavior to the &lt;code&gt;Event::$actsAs&lt;/code&gt; attribute, but this would involve the editing of a piece of source code.&lt;/p&gt;

&lt;p&gt;Thanks to &lt;code&gt;CallbackBehavior&lt;/code&gt; you can attach your behavior automatically to the &lt;code&gt;Event&lt;/code&gt; model by naming it &lt;code&gt;EventDoSomethingCallbackBehavior&lt;/code&gt; (where &lt;code&gt;DoSomething&lt;/code&gt; can be replaced by anything you wish), and then enable it as an add-on, or place it within an enabled module.&lt;/p&gt;

&lt;p&gt;This way, &lt;code&gt;CallbackBehavior&lt;/code&gt; will take care of attaching your custom behaviors following such naming convention to the respective models, and the event listeners they implement will be correctly triggered.&lt;/p&gt;

&lt;h2 id=&quot;toc_3&quot;&gt;Unbinding custom callbacks&lt;/h2&gt;

&lt;p&gt;If you chose to attach &lt;code&gt;CallbackBehavior&lt;/code&gt; with &lt;code&gt;callbackManager&lt;/code&gt; set to &lt;code&gt;true&lt;/code&gt;, you might also decide to unbind single listeners. For example, if you had a custom callback behavior like this:&lt;/p&gt;

&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;
class EventTestingCallbackBehavior extends ModelBehavior {
    public function afterSave() {
        $this-&amp;gt;log(&#039;afterSave&#039;, &#039;callback&#039;);
    }
    public function afterDelete() {
        $this-&amp;gt;log(&#039;afterDelete&#039;, &#039;callback&#039;);
    }
}&lt;/pre&gt;

&lt;p&gt;If later on you wanted to get rid of its &lt;code&gt;afterDelete()&lt;/code&gt; callback while doing a specific operation, you might call:&lt;/p&gt;

&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;
BeLib::getObject(&#039;BeCallbackManager&#039;)-&amp;gt;unbind(&#039;Event.AfterDelete&#039;, array(
    &#039;EventTestingCallbackBehavior&#039;, &#039;afterDelete&#039;
));&lt;/pre&gt;

&lt;p&gt;This way, the &lt;code&gt;EventTestingCallbackBehavior::afterDelete()&lt;/code&gt; method would be detached from the &lt;code&gt;Event.AfterDelete&lt;/code&gt; event. Please, read &lt;a href=&quot;#unbind&quot;&gt;&lt;code&gt;BeCallbackManager::unbind()&lt;/code&gt;&lt;/a&gt; documentation for further details.&lt;/p&gt;

&lt;h2 id=&quot;toc_4&quot;&gt;Adding callbacks on-the-fly&lt;/h2&gt;

&lt;p&gt;If you chose to attach &lt;code&gt;CallbackBehavior&lt;/code&gt; with &lt;code&gt;callbackManager&lt;/code&gt; set to &lt;code&gt;true&lt;/code&gt;, you might also decide to add custom listeners on the fly to model events. For example, if you attached &lt;code&gt;CallbackBehavior&lt;/code&gt; to the &lt;code&gt;Event&lt;/code&gt; model, you would have the chance to listen to those events: &lt;code&gt;Event.Beforefind&lt;/code&gt;, &lt;code&gt;Event.AfterFind&lt;/code&gt;, &lt;code&gt;Event.BeforeValidate&lt;/code&gt;, &lt;code&gt;Event.BeforeSave&lt;/code&gt;, &lt;code&gt;Event.AfterSave&lt;/code&gt;, &lt;code&gt;Event.BeforeDelete&lt;/code&gt;, &lt;code&gt;Event.AfterDelete&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Thus, this would work:&lt;/p&gt;

&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;
BeLib::getObject(&#039;BeCallbackManager&#039;)-&amp;gt;bind(&#039;Event.BeforeValidate&#039;, function ($model) {
    /* Do some custom validation rules. */
    return true;
});&lt;/pre&gt;

&lt;p&gt;Please, refer to the documentation for &lt;a href=&quot;#bind&quot;&gt;&lt;code&gt;BeCallbackManager::bind()&lt;/code&gt;&lt;/a&gt; for further details.&lt;/p&gt;

&lt;h1 id=&quot;toc_5&quot;&gt;&lt;code&gt;BeCallbackManager&lt;/code&gt; class reference&lt;/h1&gt;

&lt;p&gt;BEdita implements a basic event system. You can attach custom functions as listeners for built-in events, and you can even trigger your custom events.&lt;/p&gt;

&lt;h2 id=&quot;toc_6&quot;&gt;&lt;span id=&quot;bind&quot;&gt;&lt;code&gt;function bind(string $eventName, mixed $listener)&lt;/code&gt;&lt;/span&gt;&lt;/h2&gt;

&lt;p&gt;Bind a listener to an event.&lt;/p&gt;

&lt;h3 id=&quot;toc_7&quot;&gt;Params&lt;/h3&gt;

&lt;ul&gt;
	&lt;li&gt;&lt;code&gt;$eventName&lt;/code&gt;: name of the event to be listened.&lt;/li&gt;
	&lt;li&gt;
	&lt;p&gt;&lt;code&gt;$listener&lt;/code&gt;: callable to be invoked when the event is triggered.&lt;/p&gt;

	&lt;p&gt;This can be either an anonymous function (PHP ≥ 5.3.0) or a fully qualified name of a callable method, like a string (e.g.: &lt;code&gt;&#039;my_function&#039;&lt;/code&gt;) or an array containing a class name and one of its methods (e.g.: &lt;code&gt;array(&#039;MyClass&#039;, &#039;myPublicMethod&#039;)&lt;/code&gt;). Please note that CakePHP&#039;s &lt;code&gt;ClassRegistry&lt;/code&gt; will be used in this case to obtain an instance of the given class.&lt;/p&gt;
	&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;toc_8&quot;&gt;Examples&lt;/h3&gt;

&lt;p&gt;Bind a closure to an event:&lt;/p&gt;

&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;
$eventManager = BeLib::getObject(&#039;BeCallbackManager&#039;);

$eventManager-&amp;gt;bind(&#039;MyModel.AfterSave&#039;, function ($model, $created, $event) {
    CakeLog::write(&#039;callback&#039;, &#039;Saved object of type &quot;MyModel&quot;&#039;);
});&lt;/pre&gt;

&lt;p&gt;Bind a model method to a custom event:&lt;/p&gt;

&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;
$eventManager = BeLib::getObject(&#039;BeCallbackManager&#039;);

$eventManager-&amp;gt;bind(&#039;Cart.AfterPurchase&#039;, array(&#039;PurchaseHistory&#039;, &#039;purchaseCompleted&#039;));&lt;/pre&gt;

&lt;h2 id=&quot;toc_9&quot;&gt;&lt;span id=&quot;unbind&quot;&gt;&lt;code&gt;function unbind(string $eventName = null, mixed $listener = null)&lt;/code&gt;&lt;/span&gt;&lt;/h2&gt;

&lt;p&gt;Unbinds a listener from an event. If called without any argument, all events listeners are cleared.&lt;/p&gt;

&lt;h3 id=&quot;toc_10&quot;&gt;Params&lt;/h3&gt;

&lt;ul&gt;
	&lt;li&gt;&lt;code&gt;$eventName&lt;/code&gt;: name of the event. If omitted or null, the given &lt;code&gt;$listener&lt;/code&gt; will be removed from all events.&lt;/li&gt;
	&lt;li&gt;&lt;code&gt;$listener&lt;/code&gt;: callable to be unbinded. If omitted or null, the given &lt;code&gt;$eventName&lt;/code&gt; will be completely cleared.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;toc_11&quot;&gt;Examples&lt;/h3&gt;

&lt;p&gt;Unbind a closure from an event:&lt;/p&gt;

&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;
$eventManager = BeLib::getObject(&#039;BeCallbackManager&#039;);

$listener = function ($model, $query, $event) { /* Do something... */ };
$eventManager-&amp;gt;bind(&#039;MyModel.BeforeFind&#039;, $listener);
// ...
$eventManager-&amp;gt;unbind(&#039;MyModel.BeforeFind&#039;, $listener);&lt;/pre&gt;

&lt;p&gt;Clear all listeners for an event:&lt;/p&gt;

&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;
$eventManager = BeLib::getObject(&#039;BeCallbackManager&#039;);

$eventManager-&amp;gt;bind(&#039;MyModel.MyEvent&#039;, function () { /* ... */ });
$eventManager-&amp;gt;bind(&#039;MyModel.MyEvent&#039;, function () { /* ... */ });
// ...
$eventManager-&amp;gt;unbind(&#039;MyModel.MyEvent&#039;);&lt;/pre&gt;

&lt;h2 id=&quot;toc_12&quot;&gt;&lt;span id=&quot;trigger&quot;&gt;&lt;code&gt;function trigger(string $eventName, array $eventData = array())&lt;/code&gt;&lt;/span&gt;&lt;/h2&gt;

&lt;p&gt;Trigger an event (possibly any event) passing custom data.&lt;/p&gt;

&lt;p&gt;For model-related events (or class-related events in general), &lt;code&gt;$eventName&lt;/code&gt; is usually the class name the event refers to, followed by a dot, followed by a self-explanatory event name (both model name and event name are &lt;strong&gt;camel cased&lt;/strong&gt;). You are encouraged to follow this convention.&lt;/p&gt;

&lt;h3 id=&quot;toc_13&quot;&gt;Params&lt;/h3&gt;

&lt;ul&gt;
	&lt;li&gt;&lt;code&gt;$eventName&lt;/code&gt;: name of the event to be triggered.&lt;/li&gt;
	&lt;li&gt;&lt;code&gt;$eventData&lt;/code&gt;: array of data to be passed as arguments to listeners. The event will be always passed as &lt;strong&gt;last&lt;/strong&gt; argument.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;toc_14&quot;&gt;Return values&lt;/h3&gt;

&lt;p&gt;The triggered event is returned.&lt;/p&gt;

&lt;h3 id=&quot;toc_15&quot;&gt;Examples&lt;/h3&gt;

&lt;p&gt;Trigger a custom event:&lt;/p&gt;

&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;
$eventManager = BeLib::getObject(&#039;BeCallbackManager&#039;);

$eventManager-&amp;gt;bind(&#039;MyEvent&#039;, function ($a, $b, $event) {
    CakeLog::write(&#039;callback&#039;, $event-&amp;gt;name . &#039;_&#039; . ($a + $b));
    return 42;
});
$evt = $eventManager-&amp;gt;trigger(&#039;MyEvent&#039;, array(2, 3));  // Will result in logging &#039;MyEvent_5&#039; to &#039;callback.log&#039;.
echo($evt-&amp;gt;result);  // Outputs: &#039;42&#039;.&lt;/pre&gt;
</description><pubDate>Tue, 21 Apr 2015 18:40:57 +0200</pubDate><link>http://docs3.bedita.net/core/event-system-and-callbacks</link><guid>http://docs3.bedita.net/core/event-system-and-callbacks</guid></item><item><title>Exception handling</title><description>&lt;hr/&gt;&lt;p&gt;Since 3.6.0 version&amp;nbsp;BEdita&amp;nbsp;ships with a redesigned exception handling system that gives better error responses to client requests.&lt;/p&gt;

&lt;p&gt;With this new design every html/json/xml request will be served with the right response content type (text/html, application/json, text/xml). In this way all errors thrown by an Exception are consistent, output the expected type and set up the same &lt;code&gt;$error&lt;/code&gt; var to the view.&lt;/p&gt;

&lt;p&gt;In order to achieve this the following new components have been introduced:&lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;new HTTP exceptions&lt;/li&gt;
	&lt;li&gt;a new Exception handler&lt;/li&gt;
	&lt;li&gt;new &lt;a href=&quot;/responsehandler-component&quot;&gt;ResponseHandler&lt;/a&gt; components,&amp;nbsp;&lt;a href=&quot;/jsonview-and-xmlview&quot;&gt;JsonView and XmlView&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;HTTP Exceptions&lt;/h1&gt;

&lt;p&gt;In &lt;code&gt;bedita-app/bedita_exceptions.php&lt;/code&gt;&amp;nbsp; common http error status codes are&amp;nbsp; mapped&amp;nbsp;with exceptions as &lt;code&gt;BeditaBadRequestException&lt;/code&gt;, &lt;code&gt;BeditaNotFoundException&lt;/code&gt;, etc..&lt;/p&gt;

&lt;p&gt;Every Exception sets the right status code and a corresponding message, if any is passed.&lt;br /&gt;
For example&lt;/p&gt;

&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;
/**
* Represents an HTTP 404 error
*/
class BeditaNotFoundException extends BeditaException {
	/**
	* Constructor
	*
	* @param string $message If no message is given &#039;Not Found&#039; will be the message
	* @param mixed $details The exception details
	* @param $res The result status
	* @param int $code Status code, default to 404
	*/
	public function __construct($message = null, $details = null, $res = self::ERROR, $code = 404) {
		if (empty($message)) {
			$message = &#039;Not Found&#039;;
		}
		parent::__construct($message, $details, $res, $code);
	}
}
&lt;/pre&gt;

&lt;h1&gt;Introducing new Exception Handler&lt;/h1&gt;

&lt;p&gt;While previously exceptions were handled through a &lt;code&gt;try {} catch() {}&lt;/code&gt; block in &lt;strong&gt;index.php&lt;/strong&gt; now in &lt;kbd&gt;bedita-app/config/bootstrap.php&lt;/kbd&gt; we are using&amp;nbsp; &lt;code&gt;set_exception_handler()&lt;/code&gt; PHP function.&lt;br /&gt;
For shell scripts the exception handler is defined in &lt;code&gt;BeditaBaseShell::__construct()&lt;/code&gt; instead.&lt;/p&gt;

&lt;p&gt;In order to adopt new errors handling in old frontend apps be sure to remove the &lt;kbd&gt;try catch&lt;/kbd&gt; block from &lt;kbd&gt;app/webroot/index.php &lt;/kbd&gt;replacing it with&lt;/p&gt;

&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;
$Dispatcher = new Dispatcher();
$Dispatcher-&amp;gt;dispatch();
&lt;/pre&gt;

&lt;p&gt;The default exception handler instantiates an &lt;code&gt;AppError&lt;/code&gt;&amp;nbsp;class located at &lt;kbd&gt;bedita-app/app_error.php&lt;/kbd&gt;&amp;nbsp;that takes care of preparing error data for the client and tries to render a view.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$error&lt;/code&gt; var is identical for any type of response (html/xml/json) and contains the following keys:&lt;/p&gt;

&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;
&#039;status&#039; =&amp;gt; null, // http status code
&#039;code&#039; =&amp;gt; null, // error code
&#039;message&#039; =&amp;gt; null, // error message
&#039;details&#039; =&amp;gt; null, // error details
&#039;moreInfo&#039; =&amp;gt; null, // url to look for more information
&#039;url&#039; =&amp;gt; null // url that caused the error
&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;Note that at the current state some keys are always empty&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Following this schema the &lt;code&gt;AppError::setError()&lt;/code&gt; method sets the &lt;code&gt;App::error&lt;/code&gt; property to be serialized and sends the right header to the client based on the http error code thrown.&lt;/p&gt;

&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;
$this-&amp;gt;controller-&amp;gt;ResponseHandler-&amp;gt;sendStatus($this-&amp;gt;error[&#039;status&#039;]);
$this-&amp;gt;controller-&amp;gt;set(array(
	&#039;error&#039; =&amp;gt; $this-&amp;gt;error,
	&#039;_serialize&#039; =&amp;gt; array(&#039;error&#039;)
));
&lt;/pre&gt;

&lt;h2&gt;Setup custom exceptions handler&lt;/h2&gt;

&lt;p&gt;By default &lt;kbd&gt;bedita-app/libs/errors/be_exception_handler.php&lt;/kbd&gt; is used but it is possible to write a custom handler and set it up from configuration. To do so in frontend app you can edit &lt;strong&gt;frontend.cfg.php&lt;/strong&gt; in &lt;kbd&gt;app/config&lt;/kbd&gt; folder&lt;/p&gt;

&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;
Configure::write(&#039;Exception&#039;, array(
	&#039;handler&#039; =&amp;gt; array(
		&#039;class&#039; =&amp;gt; &#039;MyExceptionHandler&#039;,
		&#039;method&#039; =&amp;gt; &#039;myHandleExceptions&#039;
	)
));
&lt;/pre&gt;

&lt;p&gt;The custom class should be placed in &lt;kbd&gt;bedita-app/libs/errors&lt;/kbd&gt; or &lt;kbd&gt;app/libs/errors&lt;/kbd&gt; in frontend app.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Rarely you would use custom exceptions handling&amp;nbsp;in backend, in this case you need to configure it in&lt;/em&gt; &lt;kbd&gt;bedita-app/config/bedita.cfg.php&lt;/kbd&gt; (possible, but NOT recommended)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The custom method accepts an Exception as argument and it has to be defined as public static&lt;/strong&gt;, so following the above configuration we should create the file &lt;kbd&gt;app/libs/errors/my_exception_handler.php&lt;/kbd&gt;&lt;/p&gt;

&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;
class MyExceptionHandler extends Object {

	/**
	* Custom method to handle Exceptions
	*
	* @param Exception $exception
	* @return void
	*/
	public static function myHandleExceptions(Exception $exception) {
		// code here
	}

}
&lt;/pre&gt;

&lt;h1&gt;ResponseHandler Component, JsonView and XmlView&lt;/h1&gt;

&lt;p&gt;It&amp;nbsp;is responsible to respond in the right way to client requests. It&#039;s used by &lt;code&gt;AppError&lt;/code&gt; to send the correct status code and set the &lt;code&gt;$error&lt;/code&gt; var that &lt;a href=&quot;/responsehandler-component&quot;&gt;ResponseHandler&lt;/a&gt;, will eventually serialize it in the right format (json, xml) setting up the right view (&lt;a href=&quot;/jsonview-and-xmlview&quot;&gt;JsonView, XmlView&lt;/a&gt;)&lt;/p&gt;
</description><pubDate>Fri, 10 Apr 2015 11:15:27 +0200</pubDate><link>http://docs3.bedita.net/core/exception-handling</link><guid>http://docs3.bedita.net/core/exception-handling</guid></item><item><title>Debug toolkit activation</title><description>&lt;hr/&gt;&lt;p&gt;Since BEdita &lt;strong&gt;3.4&lt;/strong&gt; it is possibile to use the&amp;nbsp; &lt;a href=&quot;https://github.com/cakephp/debug_kit&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;CakePHP DebugKit&lt;/strong&gt;&lt;/a&gt;: a debugging toolbar and enhanced debugging tools for CakePHP applications.&lt;/p&gt;

&lt;p&gt;Steps to activate:&lt;/p&gt;

&lt;ol&gt;
	&lt;li&gt;get the forked version of debug_kit via github (1.3 branch only) simply using:&amp;nbsp;&amp;nbsp;&lt;code&gt;git clone -b 1.3 --single-branch https://github.com/bedita/debug_kit.git bedita-app/plugins/debug_kit &lt;/code&gt;&amp;nbsp; from BEdita core root folder [&lt;strong&gt;NOTE&lt;/strong&gt;: --single-branch option is valid from git version 1.7.10].&lt;/li&gt;
	&lt;li&gt;write&amp;nbsp;&lt;code&gt;$config[&#039;debugKit&#039;] = true;&lt;/code&gt; in &lt;em&gt;bedita-app/config/bedia.cfg.php&lt;/em&gt;&amp;nbsp; (activate for both backend/frontend) or just in frontend.cfg.php (frontend only)&lt;/li&gt;
	&lt;li&gt;now reload your application, you will see the &lt;u&gt;&lt;em&gt;cake&lt;/em&gt;&lt;/u&gt; toolbar in the upper right corner&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;Happy debugging :)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; to see sql queries in &lt;u&gt;&lt;em&gt;sql_log&lt;/em&gt;&lt;/u&gt; you should write as usual &lt;code&gt;Configure::write(&#039;debug&#039;, 2);&lt;/code&gt; in &lt;em&gt;config/core.php&lt;/em&gt;&lt;/p&gt;
</description><pubDate>Wed, 08 Apr 2015 17:23:15 +0200</pubDate><link>http://docs3.bedita.net/core/debug-toolkit-activation</link><guid>http://docs3.bedita.net/core/debug-toolkit-activation</guid></item><item><title>ResponseHandler Component</title><description>&lt;hr/&gt;&lt;p&gt;This component is always attached to any controller and automatically takes care of rendering the right type of view when json or xml are requested. It checks &lt;em&gt;&quot;Accept&quot;&lt;/em&gt; request header, parses url extensions (.json/.xml) and tells the controller to use JsonView or XmlView.&lt;/p&gt;

&lt;p&gt;For example in a frontend app: calling from a client an url like &lt;code&gt;http://example.com/sample.json&lt;/code&gt; or using jQuery&lt;/p&gt;

&lt;pre class=&quot;brush: javascript; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;
$.ajax({
	url: &#039;/other_sample&#039;,
	type: &#039;get&#039;,
	dataType: &#039;json&#039;
});
&lt;/pre&gt;

&lt;p&gt;we force ResponseHandler to respond as json to client.&lt;/p&gt;

&lt;p&gt;JsonView and XmlView views check if a special key named &lt;code&gt;_serialize&lt;/code&gt;&amp;nbsp;is in viewVars and&amp;nbsp; serialize all viewVars found in it&amp;nbsp;to present the payload to client.&lt;/p&gt;

&lt;p&gt;Following the example above&lt;/p&gt;

&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;
public function otherSample() {
	$langs = array(&#039;eng&#039; =&amp;gt; &#039;English&#039;, &#039;ita&#039; =&amp;gt; &#039;Italian&#039;);
	$this-&amp;gt;set({
		&#039;langs&#039; =&amp;gt; $langs,
		&#039;_serialize&#039; =&amp;gt; array(&#039;langs&#039;)
	});
}
&lt;/pre&gt;

&lt;p&gt;outputs to client&lt;/p&gt;

&lt;pre class=&quot;brush: javascript; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;
{
	&quot;langs&quot;: {
		&quot;eng&quot;: &quot;English&quot;,
		&quot;ita&quot;: &quot;Italian&quot;
	}
}
&lt;/pre&gt;

&lt;h1&gt;Sending&amp;nbsp;Headers&lt;/h1&gt;

&lt;p&gt;The ResponseHandler component is also very useful to send http status code to clients, for example&lt;/p&gt;

&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;
$this-&amp;gt;ResponseHandler-&amp;gt;sendStatus(400);
&lt;/pre&gt;

&lt;p&gt;Sends a &lt;em&gt;&quot;Bad Request&quot;&lt;/em&gt; header.&lt;/p&gt;

&lt;p&gt;or to send any generic header&lt;/p&gt;

&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;
// send content type image/png header to client
$this-&amp;gt;RequestHandler-&amp;gt;sendHeader(&#039;Content-Type: image/png&#039;);
// the same as above
$this-&amp;gt;RequestHandler-&amp;gt;sendHeader(&#039;Content-Type&#039;, &#039;image/png&#039;);
&lt;/pre&gt;

&lt;h1&gt;Setting Type&lt;/h1&gt;

&lt;p&gt;To force a specific type (json or xml)&lt;/p&gt;

&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;
$this-&amp;gt;ResponseHandler-&amp;gt;setType(&#039;json&#039;);&lt;/pre&gt;

&lt;p&gt;or do it globally&lt;/p&gt;

&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;
public $components = array(
	&#039;ResponseHandler&#039; =&amp;gt; array(&#039;type&#039; =&amp;gt; &#039;json&#039;)
);
&lt;/pre&gt;

&lt;h1&gt;Disabling Automatic Response&lt;/h1&gt;

&lt;p&gt;If you don&#039;t want to use ResponseHandler you can disable it in any method of your controller&lt;/p&gt;

&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;
$this-&amp;gt;ResponseHandler-&amp;gt;enabled = false;&lt;/pre&gt;

&lt;p&gt;or globally&lt;/p&gt;

&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;
public $components = array(
	&#039;ResponseHandler&#039; =&amp;gt; array(&#039;enabled&#039; =&amp;gt; false)
);&lt;/pre&gt;

&lt;p&gt;Pay attention that disabling ResponseHandler you lose the magic json/xml handling, you have to manage it manually.&lt;/p&gt;
</description><pubDate>Fri, 13 Mar 2015 14:15:20 +0100</pubDate><link>http://docs3.bedita.net/core/responsehandler-component</link><guid>http://docs3.bedita.net/core/responsehandler-component</guid></item><item><title>JsonView and XmlView</title><description>&lt;hr/&gt;&lt;p&gt;Whenever you need to output json or xml content you can use those special views. Normally BEdita apps automatically use the right View through ResponseHandler component but you can use them whenever you want: for example if you have disabled the ResponseHandler (not recommended) or if you want to force some output.&lt;/p&gt;
&lt;p&gt;To use those views setup them in your controller like&lt;/p&gt;
&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;
$this-&amp;gt;view = &#039;Json&#039;;
&lt;/pre&gt;
&lt;p&gt;or&lt;/p&gt;
&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;
$this-&amp;gt;view = &#039;Xml&#039;;&lt;/pre&gt;
&lt;p&gt;Those views check if a special key named &lt;em&gt;&quot;_serialize&quot;&lt;/em&gt; is in viewVars and if so serialize all viewVars found in &lt;em&gt;&quot;_serialize&quot;&lt;/em&gt; to present the payload to client.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;
$this-&amp;gt;view = &#039;Json&#039;;
$this-&amp;gt;set(&#039;section&#039;, $this-&amp;gt;Section-&amp;gt;find(&#039;all&#039;));
$this-&amp;gt;set(&#039;otherData&#039;, array(...));
$this-&amp;gt;set(&#039;_serialize&#039;, array(&#039;section&#039;, &#039;otherData&#039;));
&lt;/pre&gt;
&lt;p&gt;will output the &lt;code&gt;json_encode()&lt;/code&gt; of &lt;code&gt;View::viewVars[&#039;section&#039;]&lt;/code&gt; and &lt;code&gt;View::viewVars[&#039;otherData&#039;]&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Here a frontend app example where ResponseHandler is disabled and json response is handled manually&lt;/p&gt;
&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;
class PagesController extends AppController {
public $components = array(
&#039;ResponseHandler&#039; =&amp;gt; array(&#039;enabled&#039; =&amp;gt; false)
);
public function myMethod() {
$this-&amp;gt;view = &#039;Json&#039;;
$this-&amp;gt;RequestHandler-&amp;gt;respondAs(&#039;json&#039;);
$this-&amp;gt;set(&#039;object&#039;, $this-&amp;gt;loadObj(&#039;nick-object&#039;);
$this-&amp;gt;set(&#039;_serialize&#039;, array(&#039;object&#039;));
}
}&lt;/pre&gt;
&lt;p&gt;If no &lt;em&gt;&quot;_serialize&quot;&lt;/em&gt; view var is found the JsonView or XmlView will try to render a standard view file. It is useful for example if you need to manipulate data before serializing it. Removing &lt;em&gt;&quot;_serialize&quot;&lt;/em&gt;&amp;nbsp;from above example you need to add a view file named &lt;code&gt;my_method.tpl&lt;/code&gt; in &lt;code&gt;views/pages/ folder &lt;/code&gt;and manually build the json you want to output.&lt;/p&gt;
&lt;p&gt;XmlView accepts another special key named &lt;em&gt;&quot;_rootNode&quot;&lt;/em&gt;&amp;nbsp;that you can define to explicit the xml root tag. If it&#039;s not defined the &lt;code&gt;&amp;lt; response &amp;gt;&amp;lt; /response &amp;gt;&lt;/code&gt; tag is used.&lt;br /&gt;
		Example:&lt;/p&gt;
&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;
$this-&amp;gt;set(array(
&#039;object&#039; =&amp;gt; $object,
&#039;_serialize&#039; =&amp;gt; &#039;object&#039;,
&#039;_rootNode&#039; =&amp;gt; &#039;object&#039;
));&lt;/pre&gt;
&lt;p&gt;will output &lt;code&gt;$object&lt;/code&gt; in xml format using &lt;i&gt;object&lt;/i&gt; tag as root&lt;/p&gt;
&lt;pre class=&quot;brush: xml; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;
&lt;object&gt;
   &lt;id&gt;1&lt;/id&gt;
   ...
&lt;/object&gt;
&lt;/pre&gt;
&lt;p&gt;while&lt;/p&gt;
&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;
$this-&amp;gt;set(array(
&#039;object&#039; =&amp;gt; $object,
&#039;_serialize&#039; =&amp;gt; &#039;object&#039;
));&lt;/pre&gt;
&lt;p&gt;will output&lt;/p&gt;
&lt;pre class=&quot;brush: xml; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;
&lt;response&gt;
  &lt;object&gt;
    &lt;id&gt;1&lt;/id&gt;
    ...
 &lt;/object&gt;
&lt;/response&gt;
&lt;/pre&gt;
</description><pubDate>Fri, 13 Mar 2015 13:43:51 +0100</pubDate><link>http://docs3.bedita.net/core/jsonview-and-xmlview</link><guid>http://docs3.bedita.net/core/jsonview-and-xmlview</guid></item><item><title>How to set up and configure external authentication services [backend]</title><description>&lt;hr/&gt;&lt;p&gt;From version &lt;strong&gt;3.4 &lt;/strong&gt;BEdita supports by default 3 external authentication services: &lt;u&gt;&lt;em&gt;Facebook&lt;/em&gt;, &lt;em&gt;Twitter&lt;/em&gt; and &lt;em&gt;Google&lt;/em&gt;&lt;/u&gt;.&lt;/p&gt;

&lt;p&gt;In order to make this services work, we need to add some configuration parameters in the backend configuration file (bedita.cfg):&lt;/p&gt;

&lt;pre&gt;
$config[&#039;extAuthParams&#039;] = array(...);
&lt;/pre&gt;

&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;Facebook&lt;/strong&gt; &lt;strong&gt;auth service setup&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Facebook communicates with other websites through Facebook Apps. So, we need to create a Facebook App first:&amp;nbsp;&lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;Go to&amp;nbsp;&lt;a href=&quot;https://developers.facebook.com/&quot; target=&quot;_blank&quot;&gt;https://developers.facebook.com/&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;Click &quot;&lt;strong&gt;Apps&lt;/strong&gt;&quot; in the dropdown top menu&lt;/li&gt;
	&lt;li&gt;Select &quot;Create a New App&quot;&lt;/li&gt;
	&lt;li&gt;A modal window will open&lt;/li&gt;
	&lt;li&gt;Insert the name of the App, the namespace (optional) and a Category, then click the&amp;nbsp;&quot;Create App&quot; button&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once the app is created, the relative page is shown. Here we can find the App ID and the App Secret keys for our params array. Finally, we need to set our domain application:&lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;Open &quot;Settings&quot; tab from the&amp;nbsp;Facebook App Page&lt;/li&gt;
	&lt;li&gt;Add a platform&lt;/li&gt;
	&lt;li&gt;Select website from the modal window&lt;/li&gt;
	&lt;li&gt;Fill the &quot;Site url&quot; field in the &quot;Website&quot; section&lt;/li&gt;
	&lt;li&gt;Save changes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An example of the params array:&amp;nbsp;&lt;/p&gt;

&lt;pre&gt;
$config[&#039;extAuthParams&#039;] = array(
[...]
&amp;nbsp; &amp;nbsp; &#039;facebook&#039; =&amp;gt; array(
&amp;nbsp; &amp;nbsp;     &#039;keys&#039; =&amp;gt; array(
            &#039;appId&#039; =&amp;gt; &#039;[insert your appId]&#039;,
            &#039;secret&#039; =&amp;gt; &#039;[insert your app secret key]&#039;
        ),
        &#039;extraUserData&#039; =&amp;gt; array(), //additional permissions that the app requires
    ),
[...]
);&lt;/pre&gt;

&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;Twitter&amp;nbsp;auth service setup&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Also Twitter uses Apps for the external communication. Let&#039;s see how to create a twitter app:&amp;nbsp;&lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;go to&amp;nbsp;&lt;a href=&quot;https://apps.twitter.com&quot; target=&quot;_blank&quot;&gt;https://apps.twitter.com&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;span style=&quot;line-height: 1.6em;&quot;&gt;click the &quot;Create a New App&quot; button&lt;/span&gt;&lt;/li&gt;
	&lt;li&gt;fill all requested field for app creation&lt;/li&gt;
	&lt;li&gt;fill also the &quot;callback url&quot; field with your backend http address. Afterwards, the BEdita component can auto generate a custom callback url based on the login page, but Twitter needs this field however.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once the app is created, the relative page is shown. We can find the App Key and the App Secret keys switching to &quot;API keys&quot; tab, but we need to add another setting:&lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;Switch the &quot;Setting&quot; tab in the Twitter&amp;nbsp;App Page&lt;/li&gt;
	&lt;li&gt;Check &quot;Allow this application to be used to&amp;nbsp;Sign in with Twitter&quot;&lt;/li&gt;
	&lt;li&gt;Update settings&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An example of the params array:&amp;nbsp;&lt;/p&gt;

&lt;pre&gt;
$config[&#039;extAuthParams&#039;] = array(
[...]
    &#039;twitter&#039; =&amp;gt; array(
&amp;nbsp; &amp;nbsp;     &#039;keys&#039; =&amp;gt; array(
&amp;nbsp; &amp;nbsp;         &#039;appId&#039; =&amp;gt; &#039;[insert your API key]&#039;,
&amp;nbsp; &amp;nbsp; &amp;nbsp;       &#039;secret&#039; =&amp;gt; &#039;[insert your secret key]&#039;
&amp;nbsp; &amp;nbsp;     )
&amp;nbsp;    ),
[...]
);&lt;/pre&gt;

&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;Google&amp;nbsp;auth service setup&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&amp;nbsp;Let&#039;s see how to create a google app to use for our auth integration:&amp;nbsp;&lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;go to&amp;nbsp;&lt;a href=&quot;https://console.developers.google.com&quot; target=&quot;_blank&quot;&gt;https://console.developers.google.com&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;span style=&quot;line-height: 1.6em;&quot;&gt;click the &quot;Create project&quot; button&lt;/span&gt;&lt;/li&gt;
	&lt;li&gt;give the project name and project id&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once the app is created, the relative page is shown. Before the generation of secret keys, we need to set the permissions:&lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;Switch the &quot;APIs &amp;amp; auth&quot; tab in the Google App Page and select the &quot;API&quot; sub tab&lt;/li&gt;
	&lt;li&gt;Look for &quot;Google+ API&quot; and activate it&lt;/li&gt;
	&lt;li&gt;Now switch to &quot;Credentials&quot; sub tab&lt;/li&gt;
	&lt;li&gt;Click on &quot;Create new client id&quot; button&lt;/li&gt;
	&lt;li&gt;Check &quot;web application&quot;&lt;/li&gt;
	&lt;li&gt;Fill &quot;Authorized redirect URI&quot; with your bedita url&lt;/li&gt;
	&lt;li&gt;Click on &quot;Create Client ID&quot;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now we have &amp;nbsp;a Client ID and a&amp;nbsp;Client secret.&lt;/p&gt;

&lt;p&gt;An example of the params array:&amp;nbsp;&lt;/p&gt;

&lt;pre&gt;
$config[&#039;extAuthParams&#039;] = array(
[...]
&amp;nbsp; &amp;nbsp; &#039;google&#039; =&amp;gt; array(
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &#039;keys&#039; =&amp;gt; array(
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &#039;appId&#039; =&amp;gt; &#039;[your client id]&#039;,
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &#039;secret&#039; =&amp;gt; &#039;[your client secret]&#039;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ), //the permission that the app required 
        &#039;extraUserData&#039; =&amp;gt; array(), //additional permissions that the app requires
&amp;nbsp; &amp;nbsp; )
[...]
);&lt;/pre&gt;
</description><pubDate>Tue, 29 Apr 2014 10:45:54 +0200</pubDate><link>http://docs3.bedita.net/core/how-to-set-up-and-configure-external-authentication-services</link><guid>http://docs3.bedita.net/core/how-to-set-up-and-configure-external-authentication-services</guid></item><item><title>Profile your BEdita application with XHProf</title><description>&lt;hr/&gt;&lt;p&gt;&lt;/p&gt;

&lt;p&gt;In BEdita &lt;strong&gt;3.4&lt;/strong&gt; we are introducing &lt;strong&gt;XHProf&lt;/strong&gt; integration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;http://www.php.net/manual/en/book.xhprof.php&quot;&gt;XHProf&lt;/a&gt;&lt;/strong&gt; is a nice tool to profile your application performance that, unlike &lt;u&gt;XDebug&lt;/u&gt; and other tools, you can use in production systems not affecting too much the overall performance.&lt;/p&gt;

&lt;p&gt;Steps:&lt;/p&gt;

&lt;ol&gt;
	&lt;li&gt;install XHprof - remember to define output directory &lt;code&gt;xhprof.output_dir=/path/to/dir&lt;/code&gt;, with correct permissions, then verify that the script works as expected in the default UI - initially you will see and empty list of &lt;em&gt;&quot;runs&quot;&lt;/em&gt;&lt;/li&gt;
	&lt;li&gt;enable profiling in BEdita, simply write &lt;code&gt;$config[&#039;enableProfiling&#039;] = true;&lt;/code&gt; in &lt;em&gt;bedita-app/config/bedia.cfg.php&lt;/em&gt;&lt;/li&gt;
	&lt;li&gt;now use your application and point to the &lt;strong&gt;xhprof_html&lt;/strong&gt; frontend script, you will see your runs - that&#039;s it!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: Profile run file names will have this form&lt;/p&gt;

&lt;p&gt;&lt;code&gt;[run-id].[url-controllername-action].xhprof&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;url, is the full base url of your app without dots. You can then select the interesting&amp;nbsp; &quot;runs&quot;.&lt;/p&gt;

&lt;p&gt;With configuration explained above you will profile backend application and every frontend application you have in frontends.&lt;/p&gt;

&lt;p&gt;To profile only a frontend application simply comment out the line at 2. in &lt;em&gt;bedita.cfg.php &lt;/em&gt;and write the same line in &lt;em&gt;frontends/[your-frontend]/config/frontend.cfg.php&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;To profile only backend application, put in every &lt;em&gt;frontends/[your-frontend]/config/frontend.cfg.php&lt;/em&gt;&lt;br /&gt;
&amp;nbsp;&lt;code&gt;$config[&#039;enableProfiling&#039;] = false;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TECH NOTE&lt;/strong&gt;: profiling starts at &lt;code&gt;AppController::beforeFilter&lt;/code&gt; and ends at &lt;code&gt;AppController::afterFitler,&lt;/code&gt; so there&#039;s still some code not profiled, mainly bootstrap and inital config file loading.&lt;/p&gt;
</description><pubDate>Mon, 03 Mar 2014 19:08:10 +0100</pubDate><link>http://docs3.bedita.net/core/profile-your-bedita-application-with-xhprof</link><guid>http://docs3.bedita.net/core/profile-your-bedita-application-with-xhprof</guid></item><item><title>Gettext shell script</title><description>Manage i18n po files using bedita&lt;hr/&gt;&lt;div class=&quot;comment searchable&quot;&gt;
&lt;p&gt;Every template (backend, frontend, plugin) can have &lt;em&gt;translationable&lt;/em&gt; content, which is a string (a single word or a sentence) enclosed by {t} and {/t} special tag. For example, in a &lt;code&gt;.&lt;/code&gt;&lt;code&gt;tpl&lt;/code&gt; file:&lt;/p&gt;
&lt;p&gt;&lt;code&gt; {t}Title{/t}: {$object.title} &lt;/code&gt;&lt;/p&gt;
&lt;p&gt;You can create translations for these contents editing properly &lt;code&gt;.&lt;/code&gt;&lt;code&gt;po&lt;/code&gt; files, located in i18n folders: &lt;br /&gt; &lt;br /&gt;&lt;code&gt;$BEDITA_HOME/bedita-app/locale/LC_MESSAGES/&amp;lt; lang &amp;gt;/default.po&lt;/code&gt; &lt;br /&gt;&lt;code&gt;$FRONTEND_PATH/locale/LC_MESSAGES/&lt;code&gt;&amp;lt; lang &amp;gt;&lt;/code&gt;/default.po&lt;/code&gt; &lt;br /&gt;&lt;code&gt;$BEDITA_MODULES_PATH/locale/LC_MESSAGES/&lt;code&gt;&amp;lt; lang &amp;gt;&lt;/code&gt;/&amp;lt; plugin-name &amp;gt;.po&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;These files can be updated/created through BEdita gettext shell script.&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;BEdita shell script gettext&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;BEdita use gettext internazionalization and localization (i18n) system.&lt;/p&gt;
&lt;p&gt;&lt;a name=&quot;#update&quot;&gt;&lt;/a&gt;Usage of the shell script method &lt;code&gt;update&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;brush: bash; first-line: 1; gutter: false; smart-tabs: false; tab-size: 4; toolbar: false; &quot;&gt; ./cake.sh gettext update [-frontend &amp;lt; frontend-path &amp;gt;] [-plugin &amp;lt; plugin-name &amp;gt;] &lt;/pre&gt;
&lt;p&gt;To generate/merge .po/.pot files for BEdita backend:&lt;/p&gt;
&lt;pre class=&quot;brush: bash; first-line: 1; gutter: false; smart-tabs: false; tab-size: 4; toolbar: false; &quot;&gt;./cake.sh gettext update&lt;/pre&gt;
&lt;p&gt;To generate/merge .po/.pot files for a frontend (creating frontend master.pot looking at &amp;lt; frontend path &amp;gt; [use frontend /app path]):&lt;/p&gt;
&lt;div class=&quot;comment searchable&quot;&gt;
&lt;pre class=&quot;brush: bash; first-line: 1; gutter: false; smart-tabs: false; tab-size: 4; toolbar: false; &quot;&gt;./cake.sh gettext update -frontend &amp;lt; frontend-path &amp;gt; &lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;To generate/merge .po/.pot files for a plugin (create .pot and po files for specific plugin):&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;comment searchable&quot;&gt;
&lt;pre class=&quot;brush: bash; first-line: 1; gutter: false; smart-tabs: false; tab-size: 4; toolbar: false; &quot;&gt;./cake.sh gettext update -plugin &amp;lt; plugin-name &amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div class=&quot;comment searchable&quot;&gt; &lt;/div&gt;
&lt;div class=&quot;comment searchable&quot;&gt;For more details:&lt;/div&gt;
&lt;div class=&quot;comment searchable&quot;&gt; &lt;/div&gt;
&lt;div class=&quot;comment searchable&quot;&gt;
&lt;pre class=&quot;brush: bash; first-line: 1; gutter: false; smart-tabs: false; tab-size: 4; toolbar: false; &quot;&gt;./cake.sh gettext help&lt;/pre&gt;
&lt;/div&gt;</description><pubDate>Fri, 31 Aug 2012 11:55:54 +0200</pubDate><link>http://docs3.bedita.net/core/gettext-shell-script</link><guid>http://docs3.bedita.net/core/gettext-shell-script</guid></item><item><title>Migrating plugins from BEdita 3.1 to 3.2</title><description>&lt;span id=&quot;result_box&quot; lang=&quot;en&quot;&gt;&lt;span class=&quot;hps&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;hps&quot;&gt;brief guide to the&lt;/span&gt; &lt;span class=&quot;hps&quot;&gt;changes to be made&lt;/span&gt; &lt;span class=&quot;hps&quot;&gt;to upgrade&lt;/span&gt; BEdita framework.&lt;/span&gt;&lt;hr/&gt;&lt;p&gt;In order for plugins to work in BEdita 3.2 some changes may be needed for a plugin built with BEdita 3.1 to work properly.&lt;/p&gt;
&lt;p&gt;As you will see, some of the changes indicated in &lt;a href=&quot;migrating-frontends-from-3-2-to-3-1&quot;&gt;Migrating frontends from BEdita 3.1 to 3.2&lt;/a&gt; are also valid for plugins.&lt;/p&gt;
&lt;p&gt;Since BEdita 3.2 is build upon CakePHP 1.3.x, whereas 3.1 used CakePHP 1.2, you may need to look at this guide in &lt;a href=&quot;http://book.cakephp.org/#!/view/1561/Migrating-from-CakePHP-1-2-to-1-3&quot; target=&quot;_blank&quot;&gt;CakePHP cook book&lt;/a&gt; that describes migration of cakephp apps from 1.2 to 1.3.&lt;/p&gt;
&lt;h2&gt;Vendors&lt;/h2&gt;
&lt;p&gt;Support for &lt;strong&gt;vendors/css, vendors/js, and vendors/img&lt;/strong&gt; for plugins has been removed. They have been replaced with plugin (bedita module) &lt;strong&gt;webroot/css, webroot/js, and webroot/img&lt;/strong&gt; directories.&lt;br /&gt;So if you have custom files in those folder, simply move &lt;strong&gt;css img &lt;/strong&gt;and&lt;strong&gt; js&lt;/strong&gt; folders from &lt;strong&gt;&lt;em&gt;your_module/vendors/&lt;/em&gt;&lt;/strong&gt; to &lt;strong&gt;&lt;em&gt;your_module/webroot/&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you need to keep BEdita 3.1 compatibility don&#039;t move your &lt;strong&gt;css js img&lt;/strong&gt; folders but copy them into webroot, keep a copy in &lt;em&gt;vendors&lt;/em&gt; for BEdita 3.1.&lt;/p&gt;
&lt;h2&gt;View and Helpers&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;HtmlHelper::css()&lt;/code&gt; no longer has an &lt;code&gt;$inline&lt;/code&gt; parameter. Use &lt;code&gt;$options[&#039;inline&#039;]&lt;/code&gt; instead, for example if you had:&lt;br /&gt;
&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;{$html-&amp;gt;css(&quot;ui.datepicker&quot;, null, null, false)}&lt;/pre&gt;
you have to change it to:&lt;br /&gt;
&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;{$html-&amp;gt;css(&quot;ui.datepicker&quot;, null, [&#039;inline&#039;=&amp;gt;false])}&lt;/pre&gt;
or to:&lt;br /&gt;
&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;{assign_associative var=&quot;params&quot; inline=&quot;false&quot;}
{$html-&amp;gt;css(&quot;ui.datepicker&quot;, null, $params)}&lt;/pre&gt;
if you need BEdita 3.1 compatibility.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;flash()&lt;/code&gt; no longer auto echos. If you used Smarty as template engine you should replace: &lt;br /&gt;
&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;{if $session-&amp;gt;flash(&#039;error&#039;)}{/if}&lt;/pre&gt;
with:&lt;br /&gt;&lt;code&gt;
&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;{$session-&amp;gt;flash(&#039;error&#039;)}&lt;/pre&gt;
&lt;/code&gt;and simila.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;JavascriptHelper is deprecated, you should replace:  &lt;br /&gt;
&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;$javascript-&amp;gt;link()&lt;/pre&gt;
with: &lt;br /&gt;&lt;code&gt;
&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;$html-&amp;gt;script()&lt;/pre&gt;
&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;The array of smarty &lt;code&gt;assign_concat &lt;/code&gt;function now must begin with 1, if you had something like:&lt;br /&gt; &lt;code&gt;
&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;{$assign_concat var=&quot;test&quot; 0=$a 1=$b}&lt;/pre&gt;
&lt;/code&gt;simply change it to:&lt;br /&gt;
&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;{$assign_concat var=&quot;test&quot; 1=$a 2=$b}&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;</description><pubDate>Thu, 26 Jan 2012 18:06:23 +0100</pubDate><link>http://docs3.bedita.net/core/migrating-plugins-from-3-1-to-3-2</link><guid>http://docs3.bedita.net/core/migrating-plugins-from-3-1-to-3-2</guid></item><item><title>Newsletter shell script</title><description>&lt;hr/&gt;&lt;hr /&gt;
&lt;p&gt;List of methods for script, to have updated list use&lt;/p&gt;
&lt;p&gt;&lt;code&gt;./cake.sh newsletter help&lt;/code&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;import&lt;/strong&gt;: import data from specific source (default phplist)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Usage: import -f [-mailgroup ] [-from ] [-sep ] [-v] [-force]&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;-f     file to import&lt;/li&gt;
&lt;li&gt;-mailgroup         mailgroup id to associate imported users&lt;/li&gt;
&lt;li&gt;-from      import source type for example from phplist csv export&lt;/li&gt;
&lt;li&gt;-sep          separator (if needed, for example if you import from csv)&lt;/li&gt;
&lt;li&gt;-v verbose mode&lt;/li&gt;
&lt;li&gt;-force try to save with validation errors too&lt;strong&gt; &lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;createFilesListsFromPhplist&lt;/strong&gt;: create files for each list found in the phplist export file&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt; &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;addCards&lt;/strong&gt;: add cards to mailgroup, all or by category&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Usage: addCards -mailgroup [-c ]&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;-mailgroup       name of mail group / list&lt;/li&gt;
&lt;li&gt;-c        select cards by category (default: all)&lt;strong&gt; &lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;merge&lt;/strong&gt;: merge a mailgroup into another&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Usage: merge -from -to&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;-from    name of source mail group / list&lt;/li&gt;
&lt;li&gt;-to      name of destination mail group / list&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt; &lt;/p&gt;</description><pubDate>Wed, 09 Nov 2011 12:55:38 +0100</pubDate><link>http://docs3.bedita.net/core/newsletter-shell-script</link><guid>http://docs3.bedita.net/core/newsletter-shell-script</guid></item><item><title>Addressbook shell script</title><description>&lt;hr/&gt;&lt;hr /&gt;
&lt;p&gt;List of methods for script, to have updated list use&lt;/p&gt;
&lt;p&gt;&lt;code&gt;./cake.sh addressbook help&lt;/code&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;import&lt;/strong&gt;: import vcf/vcard or microsoft outlook csv file, or generic csv file&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Usage: import -f [-c ] [-m ]&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;-f     vcf/vcard or csv file to import&lt;/li&gt;
&lt;li&gt;-c       comma separated to use on import (created if not exist)&lt;/li&gt;
&lt;li&gt;-m          name of mail group to associate with imported cards&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;export&lt;/strong&gt;: export to vcf/vcard or microsoft outlook csv file&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Usage: export -f [-t ]&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;-f     vcf/vcard or csv file to export&lt;/li&gt;
&lt;li&gt;-t     &#039;vcard&#039; or &#039;csv&#039;&lt;/li&gt;
&lt;/ol&gt;</description><pubDate>Wed, 09 Nov 2011 12:41:03 +0100</pubDate><link>http://docs3.bedita.net/core/addressbook-shell-script</link><guid>http://docs3.bedita.net/core/addressbook-shell-script</guid></item><item><title>Dbadmin shell script</title><description>&lt;hr/&gt;&lt;hr /&gt;
&lt;p&gt;List of methods for script, to have updated list use&lt;/p&gt;
&lt;p&gt;&lt;code&gt;./cake.sh dbadmin help&lt;/code&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;rebuildIndex&lt;/strong&gt;: rebuild search texts index&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;checkLangStatus&lt;/strong&gt;: update lang texts &#039;status&#039; using master object status&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Usage: checkLangStatus -lang&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;buildHashMedia&lt;/strong&gt;: insert &#039;hash_file&#039; for media file.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Usage: buildHashMedia [-all]&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;-all         rebuild all &#039;hash_file&#039;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;setImageDimensions&lt;/strong&gt;: get images size and update db&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Usage: setImageDimensions [-all]&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;-all         set dimension for all images, otherwise only for image with dimensions no defined in db&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;updateVideoThumb&lt;/strong&gt;: update video thumbnail from external provider&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Usage: updateVideoThumb [-id]&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;-all         update all video, otherwise only video with no thumbnail defined in db&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;annotate&lt;/strong&gt;: add comment/editor notes to object&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Usage: annotate [-id ] [-type ] &lt;br /&gt; &lt;br /&gt; -id          object id to annotate&lt;br /&gt; -type        &#039;editor_note&#039; or &#039;comment&#039;&lt;strong&gt; &lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;orphans&lt;/strong&gt;: searche and remove orphaned objects (not in tree)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Usage: orphans -type&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;-type        model type like &#039;section&#039; or &#039;document&#039;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;importCsv&lt;/strong&gt;: import objects from csv file&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Usage: importCsv -f -type&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;-f   csv file path&lt;/li&gt;
&lt;li&gt;-type        model type like &#039;document&#039; or &#039;event&#039; to import&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;updateStreamFields&lt;/strong&gt;: update name (if empty), mime_type (if empty), size and hash_file fields of streams table&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;checkConsistency&lt;/strong&gt;: check objects for consistency on database&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;updateTreeRoot&lt;/strong&gt;: update area_id field in trees table&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;checkDbNames&lt;/strong&gt;: check database table/column names&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Usage: checkDbNames [-schema]&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;-schema      use schema file - otherwise read directly from db (default)&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;cleanup&lt;/strong&gt;: remove old items from log/job tables&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Usage: cleanup -days&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;-days        number of days to preserve from today in cleanup&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;updateCategoryName&lt;/strong&gt;: update all categories and tags unique name&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;-objectType          update categories for a specific object type (for example: document)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;importXml&lt;/strong&gt;: import BE objects from XML (in a section)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Usage: importXml -f [-s ]&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;-f   xml file path&lt;/li&gt;
&lt;li&gt;-s   section id to import&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;exportXml&lt;/strong&gt;: export BE objects to XML&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Usage: importXml -o -t&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;-o   xml output file path&lt;/li&gt;
&lt;li&gt;-t   object type: document, short_news, event,.....&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt; &lt;/p&gt;</description><pubDate>Wed, 09 Nov 2011 12:39:05 +0100</pubDate><link>http://docs3.bedita.net/core/dbadmin-shell-script</link><guid>http://docs3.bedita.net/core/dbadmin-shell-script</guid></item><item><title>Bedita shell script</title><description>&lt;hr/&gt;&lt;hr /&gt;
&lt;p&gt;List of methods for script, to have updated list use (in &lt;em&gt;bedita&lt;/em&gt; folder)&lt;/p&gt;
&lt;p&gt;&lt;code&gt;./cake.sh bedita help&lt;/code&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;init&lt;/strong&gt;: initialize a new BEdita instance from scratch&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;initDb&lt;/strong&gt;: initialize database with bedita-db sql scripts, new database with minimum data (BEdita user, basic groups one publication, one section, module data, )&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Usage: initDb [-db ] [-data ] [-nodata] [-media ]&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;-db          use db configuration specified in config/database.php&lt;/li&gt;
&lt;li&gt;-nodata         don&#039;t insert data&lt;/li&gt;
&lt;li&gt;-data           use data dump, use absolute path if not in bedita-db/&lt;/li&gt;
&lt;li&gt;-media      restore media files in&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a name=&quot;#cleanup&quot;&gt;&lt;/a&gt;&lt;strong&gt;cleanup&lt;/strong&gt;: cleanup cache, compile, log files&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Usage: cleanup [-frontend ] [-logs] [-media]&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;-frontend  clean files in [use frontend /app path]&lt;/li&gt;
&lt;li&gt;-logs        remove log files&lt;/li&gt;
&lt;li&gt;-media     clean media files in &#039;mediaRoot&#039; (default no)&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a name=&quot;#checkMedia&quot;&gt;&lt;/a&gt;&lt;strong&gt;checkMedia&lt;/strong&gt;: check media files on db and filesystem&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a name=&quot;#export&quot;&gt;&lt;/a&gt;&lt;strong&gt;export&lt;/strong&gt;: export media files and data dump in a .tar or .tar.gz file&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Usage: export [-f ] [-compress]&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;-f          file to export, default bedita-export.tar.gz&lt;/li&gt;
&lt;li&gt;-compress    gz compression (automagically applied if file extension is .gz)&lt;/li&gt;
&lt;li&gt;-nomedia     don&#039;t export media files in tar&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a name=&quot;#import&quot;&gt;&lt;/a&gt;&lt;strong&gt;import&lt;/strong&gt;: import media files and data dump&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Usage: import [-f ] [-db ] [-y]&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;-f          file to import, default bedita-export.tar.gz&lt;/li&gt;
&lt;li&gt;-db          use db configuration specified in config/database.php&lt;/li&gt;
&lt;li&gt;-y  answer always &#039;yes&#039; to questions...&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a name=&quot;#checkApp&quot;&gt;&lt;/a&gt;&lt;strong&gt;checkApp&lt;/strong&gt;: check app files ... (core.php/database.php/index.php...)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Usage: checkApp [-frontend ]&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;-frontend    check files in [use frontend /app path]&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;modules&lt;/strong&gt;: simple operations on BEdita modules list/enable/disable&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Usage: modules [-list] [-enable ] [-disable ]&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;mimeTypes&lt;/strong&gt;: update config/mime.types.php from standard mime.types file&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Usage: mimeTypes -f&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;updateObjectTypes&lt;/strong&gt;: update object_types table&lt;/li&gt;
&lt;/ul&gt;</description><pubDate>Wed, 09 Nov 2011 11:59:14 +0100</pubDate><link>http://docs3.bedita.net/core/bedita-shell-script</link><guid>http://docs3.bedita.net/core/bedita-shell-script</guid></item><item><title>Shell scripts reference</title><description>&lt;hr/&gt;&lt;p&gt;&lt;strong&gt;Core shell scripts available in BEdita&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;To call shell scripts point to &lt;em&gt;bedita&lt;/em&gt; root folder (containing bedita-app, cake,...) and type:&lt;/p&gt;
&lt;pre class=&quot;brush: bash; first-line: 1; gutter: false; smart-tabs: false; tab-size: 4; toolbar: false; &quot;&gt;./cake.sh [shell-script] [options] &lt;/pre&gt;
&lt;p&gt;on *nix systems (Linux, MacOSX,...) or&lt;/p&gt;
&lt;pre class=&quot;brush: bash; first-line: 1; gutter: false; tab-size: 4; toolbar: false; &quot;&gt;cake.bat [shell-script] [options]&lt;/pre&gt;
&lt;p&gt;on windows&lt;/p&gt;
&lt;p&gt;For example: &lt;code&gt;./cake.sh bedita cleanup &lt;/code&gt;- a common/quick way to remove compilations, cache, temporary files in general&lt;/p&gt;
&lt;p&gt;To get all available shell scripts type:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;./cake.sh help&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;To get help for a specific script type:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;./cake.sh [shell-script] help&lt;/code&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;Core scripts&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Here the main BEdita scripts &lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;./bedita-shell-script&quot;&gt;bedita&lt;/a&gt;: general purpose main script, db operations, data import/export, modules enable/disable....&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;./addressbook-shell-script&quot;&gt;addressbook&lt;/a&gt;: import/export addressobook items&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;./dbadmin-shell-script&quot;&gt;dbadmin&lt;/a&gt;: generic db operations&lt;/li&gt;
&lt;li&gt;gettext: create and merge gettext .po files (gettext php module is needed)&lt;/li&gt;
&lt;li&gt;mail: internal script to send newsletter/notifications - to use in cron jobs mainly&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;./newsletter-shell-script&quot;&gt;newsletter&lt;/a&gt;: mass imports, mailgroup merge and other newsletter operations&lt;/li&gt;
&lt;li&gt;module: plug/unplug modules, generate schema for plugins - module plugins&lt;/li&gt;
&lt;/ol&gt;</description><pubDate>Tue, 08 Nov 2011 17:46:37 +0100</pubDate><link>http://docs3.bedita.net/core/shell-scripts-reference</link><guid>http://docs3.bedita.net/core/shell-scripts-reference</guid></item><item><title>BEdita Objects: models</title><description>This article explain how the Objects Models works in BEdita&lt;hr/&gt;&lt;p&gt;This article explain how the Objects Models works in BEdita&lt;/p&gt;&lt;hr/&gt;&lt;p&gt;Every BEdita object is represented by a model that has to extend &lt;strong&gt;BEAppObjectModel&lt;/strong&gt; class or its sublcasses and that has to define some class attributes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Usually is preferable to extend a subclass of BEAppObjectModel&lt;/strong&gt; where attributes and base associations are already defined. You can find a complete set of them in &lt;strong&gt;bedita/bedita-app/app_model.php&lt;/strong&gt; file.&lt;/p&gt;
&lt;p&gt;Every model of BEdita object has to be associated by a &lt;a href=&quot;http://book.cakephp.org/view/80/hasOne&quot; target=&quot;_blank&quot;&gt;&quot;hasOne&quot;&lt;/a&gt; relation with models that manage base object tables (&lt;strong&gt;BEObject&lt;/strong&gt;, that uses &lt;em&gt;objects&lt;/em&gt; table).&lt;/p&gt;
&lt;p&gt;So having a look at &lt;strong&gt;Image&lt;/strong&gt; model located in &lt;strong&gt;bedita/bedita-app/models/objects/content/image.php&lt;/strong&gt; we can see that it extends &lt;strong&gt;BeditaStreamModel&lt;/strong&gt; that has an hasOne relation with BEObject, Content and Stream ie with the tables objects, contents and streams.&lt;/p&gt;
&lt;h2&gt;Required class attributes&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;array $modelBindings&lt;br /&gt;&lt;/strong&gt;It defines bindings with other models used in method find() of CakePHP. For example the &quot;detailed&quot; key is used automatically when you view an object detail in BEdita backend. This attribute is used by &lt;a href=&quot;http://book.cakephp.org/view/474/Containable&quot; target=&quot;_blank&quot;&gt;Containable&lt;/a&gt; behavior of CakePHP.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;array $actsAs&lt;/strong&gt;&lt;br /&gt;It defines the behaviors used by model. Define it as an empty array if you don&#039;t need it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;array $objectTypesGroups&lt;/strong&gt;&lt;br /&gt;It contains a list of groups of object type.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&quot;leafs&quot; tells if an object can be put on the publication tree structure&lt;/li&gt;
&lt;li&gt;&quot;related&quot; tells if an object will appear in the relation list when not specific list of object types is been defined (free semantic relation).&lt;/li&gt;
&lt;li&gt;&quot;multimedia&quot; tells if an object is a multimedia object&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Define as an empty array if you don&#039;t need it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;array $searchFields&lt;/strong&gt;&lt;br /&gt;It contains the score/importance of database fields used for full text search (only MySQL now) in a 1-10 range. For example:&lt;/p&gt;
&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;public $searchFields = array(
   &quot;title&quot; =&amp;gt; 10,
   &quot;creator&quot; =&amp;gt; 6,
   &quot;description&quot; =&amp;gt; 6,
   &quot;subject&quot; =&amp;gt; 4,
   &quot;abstract&quot; =&amp;gt; 4,
   &quot;body&quot; =&amp;gt; 4
);&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Meaning that &quot;title&quot; field is more important (10) than &quot;description&quot; (6) which is more important than &quot;abstract&quot; (4).&lt;/p&gt;</description><pubDate>Fri, 07 Jan 2011 16:43:58 +0100</pubDate><link>http://docs3.bedita.net/core/bedita-objects-models</link><guid>http://docs3.bedita.net/core/bedita-objects-models</guid></item><item><title>Error logs: &#039;missingController&#039; message</title><description>This article is about error log messages and the &lt;em&gt;strange&lt;/em&gt;/&lt;em&gt;mysterious&lt;/em&gt; &#039;missingController&#039; message&lt;hr/&gt;&lt;p&gt;This article is about error log messages and the &lt;em&gt;strange&lt;/em&gt;/&lt;em&gt;mysterious&lt;/em&gt; &#039;missingController&#039; message&lt;/p&gt;&lt;hr/&gt;&lt;p&gt;As you may know &lt;strong&gt;BEdita&lt;/strong&gt; uses standard &lt;a title=&quot;CakePHP logging&quot; href=&quot;http://book.cakephp.org/view/1194/Logging&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;CakePHP&lt;/strong&gt; log&lt;/a&gt; files for its own logging system.&lt;/p&gt;
&lt;p&gt;You have different sets of log files for your backend application and for every frontend application/site, namely:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;in &lt;code&gt;bedita/bedita-app/tmp/logs &lt;/code&gt;for backend error.log/debug.log files&lt;/li&gt;
&lt;li&gt;in &lt;code&gt;bedita/frontends/www.myfrontend.com/tmp/logs &lt;/code&gt;for every frontend, where path will change (substitute www.myfrontend.com with the actual frontend dir name), with usual error.log/debug.log files&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To write in these log files use the &lt;code&gt;$this-&amp;gt;log()&lt;/code&gt; method inside every BEdita controller or model.&lt;/p&gt;
&lt;p&gt;Here you will find, for example, exceptions related messages, such as stack traces, like:&lt;/p&gt;
&lt;pre class=&quot;brush: php; first-line: 1; gutter: false; tab-size: 4; toolbar: false; &quot;&gt;2011-01-11 11:11:11 Error: BeditaException - Error: object type not found File: bedita-app/models/objects/b_e_object.php - line: 522 Trace:
#0 bedita-app/controllers/frontend_controller.php(1211): BEObject-&amp;gt;getType(false)
#1 [internal function]: FrontendController-&amp;gt;section(&#039;blog&#039;, &#039;img&#039;, &#039;loadingAnimatio...&#039;)
#2 bedita-app/controllers/frontend_controller.php(1382): call_user_func_array(Array, Array)
...&lt;/pre&gt;
&lt;p&gt;That refers to some unexpected error. You may inspect this log file to find possbile bugs or unwanted behaviours of your application. These log messages can be hard to understand but if you follow source files/line numbers you may find out what the problem is.&lt;/p&gt;
&lt;p&gt;Typical messages are classic HTTP 404/500 error messages like&lt;/p&gt;
&lt;pre class=&quot;brush: php; first-line: 1; gutter: false; smart-tabs: false; tab-size: 4; toolbar: false; &quot;&gt;2010-12-13 18:47:21 Error:  500 Internal Error - missingTable: array (...)
...&lt;/pre&gt;
&lt;p&gt;&lt;code&gt; &lt;/code&gt;Other log messages are definitely more cryptic/mysterious. For example this one that we were investigating these days:&lt;/p&gt;
&lt;pre class=&quot;brush: php; first-line: 1; gutter: false; tab-size: 4; toolbar: false; &quot;&gt;2011-03-10 10:43:42 Error:  404 Not Found - missingController: array (
   &#039;BEAuthUser&#039; =&amp;gt; ...
   &#039;controller&#039; =&amp;gt; &#039;JsController&#039;,
   &#039;controllerName&#039; =&amp;gt; &#039;Js&#039;,
) &lt;/pre&gt;
&lt;p&gt;Seems like an attempt to retrieve something through an URL like &lt;code&gt;/js/...&lt;/code&gt; that is normally used for javascript files. This indicates that some of your javascript links are broken, you are probably linking to a missing js file. Same applies to css or image files, for which you will find a missing &lt;strong&gt;CssController&lt;/strong&gt; o &lt;strong&gt;ImgController&lt;/strong&gt; in your log files.&lt;/p&gt;
&lt;p&gt;To easily find out which links are broken we suggest you to use a tool like &lt;a href=&quot;http://getfirebug.com/&quot; target=&quot;_blank&quot;&gt;Firebug&lt;/a&gt;: enable &quot;Net&quot; view and look for 404 errors in HTTP GET calls highlited in red. Look at the screenshots in this page for an example.&lt;/p&gt;</description><pubDate>Tue, 15 Mar 2011 16:26:04 +0100</pubDate><link>http://docs3.bedita.net/core/error-logs-missingcontroller-message</link><guid>http://docs3.bedita.net/core/error-logs-missingcontroller-message</guid></item><item><title>BEdita Objects: database tables</title><description>Description of BEdita object database table structure&lt;hr/&gt;&lt;p&gt;Description of BEdita object database table structure&lt;/p&gt;&lt;hr/&gt;&lt;p&gt;As you can read in the &lt;a href=&quot;/backend/bedita-objects-overview&quot;&gt;overview&lt;/a&gt; article a BEdita Object consists of one or more tables. All BEdita objects have the &lt;strong&gt;objects&lt;/strong&gt; table as a common element, and they can have specific fields defined in other tables linked by a one-to-one relationship with &lt;strong&gt;objects&lt;/strong&gt; table.&lt;/p&gt;
&lt;p&gt;Every BEdita object has one row and the same id in every table involved. For example the &lt;strong&gt;image object&lt;/strong&gt; type is defined by four tables: &lt;strong&gt;objects&lt;/strong&gt;, &lt;strong&gt;contents&lt;/strong&gt;, &lt;strong&gt;streams&lt;/strong&gt; and &lt;strong&gt;images&lt;/strong&gt;. When a new image is added to BEdita a new row with the same id will be inserted in each tables.&lt;/p&gt;
&lt;p&gt;However a BEdita object can have other properties than those defined through the base object tables. It can have tags, categories, and others with their own table and are linked to the BEdita object.&lt;/p&gt;
&lt;p&gt;Integrity constraints are used between BEdita object tables and properties involved for ensure consistency of data and to perform cascading delete. In this way deleting a row on the objects table will remove all references to that object in the database. &lt;strong&gt;This is powerful but requires attention when creating schemas for new tables&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;For example  you can see below a portion of the contents schema table (MySQL version here):&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre class=&quot;brush: sql; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;CREATE TABLE `contents` (
`id` INTEGER UNSIGNED NOT NULL,  
`start_date` DATETIME NULL ,  
...  
PRIMARY KEY(id),  
FOREIGN KEY(id) REFERENCES objects(id) ON DELETE CASCADE ON UPDATE NO ACTION) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT = &#039;general contents data&#039; ;&lt;/pre&gt;
&lt;p&gt;in particular:&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre class=&quot;brush: sql; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;FOREIGN KEY(id) REFERENCES objects(id) ON DELETE CASCADE ON UPDATE NO ACTION&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;&lt;br /&gt;defines the integrity constraints between &lt;span style=&quot;text-decoration: underline;&quot;&gt;&lt;em&gt;contents.id&lt;/em&gt;&lt;/span&gt; and &lt;span style=&quot;text-decoration: underline;&quot;&gt;&lt;em&gt;objects.id&lt;/em&gt;&lt;/span&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;no row on contents can be inserted without a relative row in &lt;em&gt;objects&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;when a row in &lt;em&gt;objects &lt;/em&gt;is deleted then the relative row on &lt;em&gt;contents &lt;/em&gt;will be removed&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To see more examples have a look at &lt;strong&gt;bedita/bedita-app/config/sql/bedita_mysql_schema.sql&lt;/strong&gt;&lt;/p&gt;</description><pubDate>Fri, 07 Jan 2011 13:28:38 +0100</pubDate><link>http://docs3.bedita.net/core/bedita-objects-database-tables</link><guid>http://docs3.bedita.net/core/bedita-objects-database-tables</guid></item><item><title>BEdita Objects overview</title><description>Understanding BEdita objects&lt;hr/&gt;&lt;p&gt;Understanding BEdita objects&lt;/p&gt;&lt;hr/&gt;&lt;p&gt;&lt;strong&gt;A BEdita Object is the main item on which is built BEdita&lt;/strong&gt;. There are many types of objects in BEdita as document, gallery, section, image, etc... and you can create as many as you want through new &lt;a href=&quot;/core/bedita-module-as-a-cakephp-plugin&quot;&gt;modules&lt;/a&gt; and &lt;a href=&quot;/core/customizing-bedita-with-addons&quot;&gt;addons&lt;/a&gt;. You can see a list of these objects in &lt;strong&gt;object_types&lt;/strong&gt; table where the field &lt;em&gt;module_name&lt;/em&gt; is the main module where you can handle the corresponding object.&lt;/p&gt;
&lt;p&gt;From the &lt;a href=&quot;/core/bedita-objects-database-tables&quot;&gt;database point of view&lt;/a&gt; a BEdita Object consists of a &lt;strong&gt;common base element&lt;/strong&gt; (the base table &lt;strong&gt;objects&lt;/strong&gt;) that may be extended with &lt;strong&gt;other object elements&lt;/strong&gt; (i.e. other tables such as contents, cards, etc..) that add specific persistent properties to objects and &lt;strong&gt;other common properties/metadata&lt;/strong&gt; such as categories, tags, geo tags, etc...&lt;/p&gt;
&lt;p&gt;You don&#039;t necessarily need to add tables to create a new object type; instead you can create as many objects as you want maintaining the database unchanged (for example documents, events and short_news objects uses the same two tables &lt;em&gt;objects&lt;/em&gt; and &lt;em&gt;contents&lt;/em&gt;). If you need to add a table for your object you will have already a base on which building it.&lt;/p&gt;
&lt;p&gt;From the &lt;a href=&quot;/core/bedita-objects-models&quot;&gt;model point of view&lt;/a&gt; a BEdita Object is a CakePHP model that has to extend &lt;code&gt;BEAppObjectModel&lt;/code&gt; class or one of its subclasses (located in &lt;strong&gt;bedita/bedita-app/app_model.php&lt;/strong&gt;) and has to define some required class attributes.&lt;/p&gt;
&lt;p&gt;Remember that the object type names (in object_types table) are underscored while the relative model class names are CamelCased. So if you have a model class named &lt;strong&gt;MyFantasticObject&lt;/strong&gt; the object type name will be &lt;strong&gt;my_fantatstic_object&lt;/strong&gt;.&lt;/p&gt;</description><pubDate>Fri, 07 Jan 2011 09:33:20 +0100</pubDate><link>http://docs3.bedita.net/core/bedita-objects-overview</link><guid>http://docs3.bedita.net/core/bedita-objects-overview</guid></item><item><title>How to Create BEdita Translations</title><description>A brief introduction on how to create a BEdita translation&lt;hr/&gt;&lt;p&gt;A brief introduction on how to create a BEdita translation&lt;/p&gt;&lt;hr/&gt;&lt;p&gt;To see how to enable translations have a look at &lt;a href=&quot;/extend/translation-packages&quot; target=&quot;_self&quot;&gt;&quot;Enable translation&quot;&lt;/a&gt; paragraph.&lt;/p&gt;
&lt;p&gt;BEdita translations are located in &lt;strong&gt;bedita-app/locale&lt;/strong&gt; folder and each language package consists of a folder named with relative &lt;a href=&quot;http://en.wikipedia.org/wiki/ISO_639-3&quot; target=&quot;_blank&quot;&gt;ISO-639-3&lt;/a&gt; codes. The structure is:&lt;br /&gt;&lt;br /&gt;
&lt;pre class=&quot;brush: bash; first-line: 1; gutter: false; tab-size: 4; toolbar: false; &quot;&gt;bedita/bedita-app/locale/(lang-code)/LC_MESSAGES/default.po&lt;/pre&gt;
&lt;br /&gt;where &lt;strong&gt;default.po&lt;/strong&gt; is the translation file. There are two methods you can follow to create your translation: in each method you&#039;ll have to edit a po file. Unless you&#039;re familiar with their format you should use a po editor. There are free tools such as &lt;a href=&quot;http://www.poedit.net/&quot;&gt;PoEdit&lt;/a&gt; which make editing and updating your po files an easy task but if you want use your favourite text editor assure to use UTF-8 to avoid problems.&lt;/p&gt;
&lt;h1&gt;Method one (shell script)&lt;/h1&gt;
&lt;p&gt;To work properly this method need &lt;a title=&quot;GNU gettext&quot; href=&quot;http://www.gnu.org/software/gettext/&quot; target=&quot;_blank&quot;&gt;gettext utilities&lt;/a&gt; installed so if you don&#039;t or you can&#039;t install it read method two. &lt;br /&gt;As first thing you have to prepare your language .po file with a correct header entry (UTF-8 charset is important).&lt;/p&gt;
&lt;p&gt;So for example if you want create a russian translation you have to create a file named &lt;strong&gt;default.po &lt;/strong&gt;in &lt;strong&gt;bedita/bedita-app/locale/rus/LC_MESSAGES&lt;/strong&gt; folder. Then you will need to edit the file headers entry. Copy them from &lt;strong&gt;bedita/bedita-app/locale/eng/LC_MESSAGES/default.po&lt;/strong&gt; file:&lt;br /&gt;&lt;br /&gt;
&lt;pre class=&quot;brush: bash; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;msgid &quot;&quot;
msgstr &quot;&quot;
&quot;Project-Id-Version: BEdita 3\n&quot;
&quot;POT-Creation-Date: 2011-01-04 16:26:49\n&quot;
&quot;PO-Revision-Date: \n&quot;
&quot;Last-Translator: \n&quot;
&quot;Language-Team: Bedita I18N &amp;amp; I10N Team\n&quot;
&quot;Language: \n&quot;
&quot;MIME-Version: 1.0\n&quot;
&quot;Content-Type: text/plain; charset=UTF-8\n&quot;
&quot;Content-Transfer-Encoding: 8bit\n&quot;
&quot;Plural-Forms: nplurals=2; plural=(n != 1);\n&quot;&lt;/pre&gt;
&lt;/p&gt;
&lt;p&gt;Save file, then open a shell, go to bedita folder and write:&lt;br /&gt;&lt;br /&gt;
&lt;pre class=&quot;brush: bash; first-line: 1; gutter: false; tab-size: 4; toolbar: false; &quot;&gt;./cake.sh gettext update&lt;/pre&gt;
&lt;br /&gt;this shell script will update master.pot file and all default.po file in locale subfolders. You will see also a translation percentage for any language. This script mantains updated every language adding new entry to translate or remove entry no more used.&lt;/p&gt;
&lt;p&gt;Once the script runs edit your default.po file translating every &lt;em&gt;msgid&lt;/em&gt; entry with relative &lt;em&gt;msgstr.&lt;/em&gt;&lt;/p&gt;
&lt;h1&gt;&lt;span style=&quot;font-size: 18px;&quot;&gt;&lt;br /&gt;Method two (copy by hand)&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;Copy &lt;strong&gt;bedita/bedita-app/locale/eng/LC_MESSAGES/default.po &lt;/strong&gt;in your translation folder and edit every &lt;em&gt;msgid&lt;/em&gt; entry with relative &lt;em&gt;msgstr&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Remember to use UTF-8 charset to edit po file.&lt;/p&gt;</description><pubDate>Tue, 04 Jan 2011 16:19:00 +0100</pubDate><link>http://docs3.bedita.net/core/how-to-create-bedita-translations</link><guid>http://docs3.bedita.net/core/how-to-create-bedita-translations</guid></item><item><title>Customizing BEdita with addons</title><description>Extending BEdita using addons folder to enhance your features in backend and frontend apps.&lt;hr/&gt;&lt;p&gt;Extending BEdita using addons folder to enhance your features in backend and frontend apps.&lt;/p&gt;&lt;hr/&gt;&lt;p&gt;Designing frontend application you could need to extend BEdita with components, models or helpers to use in backend and frontend apps too. To not mess BEdita core with not core items you should use the &lt;strong&gt;addons &lt;/strong&gt;folder. &lt;strong&gt;Addons is a place where CakePHP will search for models, components, helpers and vendors&lt;/strong&gt;. It&#039;s a conventional folder where you can put no core classes.&lt;/p&gt;
&lt;p&gt;The addons folder that you can find in bedita root folder presents some directories that are automatically added to CakePHP paths to retrieve the relative classes.&lt;/p&gt;
&lt;pre class=&quot;brush: bash; first-line: 1; gutter: false; tab-size: 4; toolbar: false; &quot;&gt;addons
|--components
|--config
|--helpers
|--models
|--vendors&lt;/pre&gt;
&lt;p&gt;For Example CakePHP will search components in &lt;strong&gt;bedita/bedita-app/controllers/components&lt;/strong&gt; and in &lt;strong&gt;bedita/addons/components&lt;/strong&gt; and so on for models, helpers and vendors.&lt;/p&gt;
&lt;h1&gt;Adding new BEdita object type&lt;/h1&gt;
&lt;p&gt;If you need a new &lt;a href=&quot;/backend/bedita-objects-overview&quot;&gt;BEdita object type&lt;/a&gt; that not require a new BEdita module you should put your Model in &lt;strong&gt;addons/models&lt;/strong&gt; folder then you&#039;ll have to enable the object type to be written in configuration and so to be used correctly in any part of BEdita. To do it go in administration module and click on addons in the left menu. There you can enable/disable BEdita object type and see a complete list of all addons available on the system.&lt;/p&gt;
&lt;p&gt;If you want manage your new BEdita object type in a module already present, add to your model the attribute &lt;code&gt;$module&lt;/code&gt;. For example if you have created a Place model and you want to see it in Addressbook module, write in you model class:&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre class=&quot;brush: bash; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;public $module = &quot;addressbook&quot;;&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;according with field &quot;name&quot; in table &quot;modules&quot;. Then enable your addon.&lt;/p&gt;
&lt;p&gt;In &lt;strong&gt;config folder&lt;/strong&gt; you can create a &lt;strong&gt;config.php&lt;/strong&gt; file and put in some global configurations that you&#039;ll have available in BEdita. For example when you add a new BEdita object you could need a free semantic relations that involve it with other BEdita objects. Write your configuration like an array named &lt;code&gt;$config&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Note that disabling a BEdita object addon all objects belonging to it will be deleted, but you will have to edit config.php if you want to remove any configuration related to that model.&lt;/p&gt;
&lt;p&gt;For more information about BEdita objects see the &lt;a href=&quot;/backend/bedita-objects-overview&quot;&gt;&quot;BEdita objects&quot; articles&lt;/a&gt;.&lt;/p&gt;</description><pubDate>Fri, 19 Feb 2010 17:13:37 +0100</pubDate><link>http://docs3.bedita.net/core/customizing-bedita-with-addons</link><guid>http://docs3.bedita.net/core/customizing-bedita-with-addons</guid></item><item><title>BEdita module as a CakePHP plugin</title><description>This article shows how to create a new BEdita module through a CakePHP plugin&lt;hr/&gt;&lt;p&gt;This article shows how to create a new BEdita module through a CakePHP plugin&lt;/p&gt;&lt;hr/&gt;&lt;p&gt;&lt;strong&gt;Creating a new module in BEdita is simple like writing a CakePHP plugin&lt;/strong&gt;. Generally a module will have a controller, one or more models, some views, at least a css that defines the module color and a special file named &lt;strong&gt;bedita_module_setup.php&lt;/strong&gt; that contains some rules and definitions to start up and hook correctly the module to BEdita. Without this file the plugin will not be recognized from BEdita as a valid module. Each BEdita module has to be stay in the &lt;strong&gt;modules&lt;/strong&gt; folder that you can find in bedita root folder.&lt;/p&gt;
&lt;p&gt;You can find a sample plugin module in bedita-app/modules/sample_module : start from here, changing files and folder names and editing some other stuff&lt;/p&gt;
&lt;p&gt;Otherwise you can build the new module from scratch using this sample module as reference. Once your module is configured properly it can be activated by the admin module web interface.&lt;/p&gt;
&lt;p&gt;Here you can find some basic rules to build your module:&lt;/p&gt;
&lt;h1&gt;modules folder&lt;/h1&gt;
&lt;p&gt;The name of your module will be the name of your plugin folder. Pay attention that the module name isn&#039;t the module label that you can see in BEdita backend square and that you will define in &lt;strong&gt;bedita_module_setup.php&lt;/strong&gt; how you can see below.&lt;/p&gt;
&lt;p&gt;The name of your module controller file has to be the same of the plugin folder. So the structure will be:&lt;/p&gt;
&lt;pre class=&quot;brush: bash; first-line: 1; gutter: false; tab-size: 4; toolbar: false; &quot;&gt;bedita-app/modules/sample_module/controllers/sample_module_controller.php&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h1&gt;&lt;br /&gt;config folder&lt;/h1&gt;
&lt;p&gt;This folder contains the fundamental &lt;strong&gt;bedita_module_setup.php&lt;/strong&gt; and a &lt;strong&gt;config.php&lt;/strong&gt; (optional) file with some global configurations. The first one will contain an array like:&lt;/p&gt;
&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;$moduleSetup = array(
    &quot;publicName&quot; =&amp;gt; &quot;Sample Module&quot;,
    &quot;author&quot; =&amp;gt; &quot;Channelweb and Chialab&quot;,
    &quot;website&quot; =&amp;gt; &quot;http://www.bedita.com&quot;,
    &quot;emailAddress&quot; =&amp;gt; &quot;info@bedita.com&quot;,
    &quot;description&quot; =&amp;gt; &quot;Example of BEdita&#039;s module plugin&quot;,
    &quot;version&quot; =&amp;gt; &quot;0.1&quot;,   
    // minimum BEdita version required by this module
    &quot;BEditaMinVersion&quot; =&amp;gt; &quot;3.1&quot;,
    // maximum BEdita version supported by this module
    //&quot;BEditaMaxVersion&quot; =&amp;gt; &quot;3.1&quot;,
    // model names that are BEdita objects: i.e. extend BEAppObjectModel  
   &quot;BEditaObjects&quot; =&amp;gt; array(&quot;SampleObject&quot;),
    // extra database tables used/needed by this module
    // &quot;tables&quot; =&amp;gt; array(&quot;sample_objects&quot;),
);
&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;publicName&lt;/em&gt; that is the module label you can see in the square box on BEdita that refers to your module, the &lt;em&gt;author&lt;/em&gt;, a &lt;em&gt;website&lt;/em&gt; of the author, a referent &lt;em&gt;email&lt;/em&gt;, the &lt;em&gt;version&lt;/em&gt;, the &lt;em&gt;BEdita minimum compatible version&lt;/em&gt;, a &lt;em&gt;description&lt;/em&gt; and an array of &lt;em&gt;new BEdita objects&lt;/em&gt; (new model names that are &lt;a href=&quot;/core/bedita-objects-overview&quot;&gt;BEdita objects&lt;/a&gt;, not just simple models) involved by module. If your module needs you can define here a &lt;em&gt;BEdita maximum version supported&lt;/em&gt; and an array of &lt;em&gt;tables&lt;/em&gt; used by your module.&lt;/p&gt;
&lt;p&gt;If you needed to define some global configurations (like relations with other objects) put it in &lt;strong&gt;config/config.php&lt;/strong&gt; file and it will be loaded in every BEdita page.  For example if your module defines a new free relation with document object add this:&lt;/p&gt;
&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;$config[&quot;objRelationType&quot;] = array(
   &quot;custom_relation&quot; =&amp;gt; array(
      &quot;hidden&quot; =&amp;gt; false,
      &quot;left&quot;      =&amp;gt; array(&quot;sample_object&quot;),
      &quot;right&quot;  =&amp;gt; array(&quot;document&quot;)
   )
);&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h1&gt;controller&lt;/h1&gt;
&lt;p&gt;Controller name, as we said, has to be the same as the plugin folder with&lt;em&gt; _controller&lt;/em&gt; suffix.&lt;br /&gt;Controller has to extend the ModulesController abstract class located in the app_controller.php file. If the module uses only a BEdita object the controller has to override some basic methods: &lt;strong&gt;index&lt;/strong&gt;, &lt;strong&gt;view&lt;/strong&gt;, &lt;strong&gt;save&lt;/strong&gt;, &lt;strong&gt;delete&lt;/strong&gt;, &lt;strong&gt;deleteSelected&lt;/strong&gt;, &lt;strong&gt;forward&lt;/strong&gt;. If your module use two or more BEdita objects then implement specific method &lt;strong&gt;view&lt;em&gt;BEditaObjectModel&lt;/em&gt;&lt;/strong&gt;, &lt;strong&gt;save&lt;em&gt;BEditaObjectModel&lt;/em&gt;&lt;/strong&gt;, &lt;strong&gt;delete&lt;em&gt;BEditaObjectModel&lt;/em&gt;&lt;/strong&gt; instead of view, save and delete. ModulesController methods (view, save, delete) will take care of routing at the correct method of your controller.&lt;/p&gt;
&lt;p&gt;A required attribute of your module controller class is:&lt;/p&gt;
&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;protected $moduleName = &#039;sample_module&#039;;&lt;/pre&gt;
&lt;p&gt;that will be the controller name with underscores.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h1&gt;model&lt;/h1&gt;
&lt;p&gt;Your module models can be of two types. A standard cakePHP model or a BEdita object model. In the second case the model will have to follow some guidelines that you can read in &lt;a href=&quot;/core/bedita-objects-overview&quot; target=&quot;_self&quot;&gt;BEdita object articles&lt;/a&gt;. However if your module uses one or more new BEdita objects, their names (&lt;em&gt;class names&lt;/em&gt;) should be placed in &lt;strong&gt;bedita_module_setup.php&lt;/strong&gt; at the key &lt;em&gt;&quot;BEditaObjects&quot;&lt;/em&gt;. Automatically they&#039;ll be inserted in object_types table and put in the cached configuration.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h1&gt;views&lt;/h1&gt;
&lt;p&gt;In &lt;strong&gt;modules/sample_module/views/sample_module&lt;/strong&gt; folder reside the views of your module. Commons BEdita tabs like (text, tags, translations, etc....) are CakePHP elements so you can reuse it from your plugin calling:&lt;/p&gt;
&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;{$view-&amp;gt;element(&#039;elementName&#039;)}&lt;/pre&gt;
&lt;p&gt;In all views should be present &lt;strong&gt;modulesmenu.tpl&lt;/strong&gt; element that contains the &lt;em&gt;on top&lt;/em&gt; modules navigation. &lt;strong&gt;view.tpl&lt;/strong&gt; should contain &lt;strong&gt;form_common_js.tpl&lt;/strong&gt; element to load standard BEdita javascript form functions.&lt;/p&gt;
&lt;h1&gt;css&lt;/h1&gt;
&lt;p&gt;Folder&lt;strong&gt; /sample_module/vendors/css&lt;/strong&gt; has to contain the &lt;strong&gt;module_color.css&lt;/strong&gt; file where you can specify the module color. This file is linked in every BEdita backend page: all modules color are always available. If you need specific css for you module put it in a file named &lt;strong&gt;module.css&lt;/strong&gt; that will be linked only in the module pages.&lt;/p&gt;
&lt;h1&gt;js&lt;/h1&gt;
&lt;p&gt;Like css also for specific javascript you want to use in your module put it in &lt;strong&gt;vendors/js/module.js&lt;/strong&gt; file. It will be linked only in the module pages.&lt;/p&gt;
&lt;h1&gt;How to create schema.php for extra tables&lt;/h1&gt;
&lt;p&gt;When you have extra tables in your setup (&lt;code&gt;$moduleSetup[&quot;tables&quot;]&lt;/code&gt;), you have to create correctly the following files: &lt;code&gt;config/sql/schema.php&lt;/code&gt;, &lt;code&gt;config/sql/mysql_schema.php&lt;/code&gt;. In order to do that, you should use cake module script. Let see how to do that, with an example in 3 steps.&lt;/p&gt;
&lt;p&gt;1. First of all, create your database table(s), and don&#039;t loose your sql creation script (you could use it, later).&lt;/p&gt;
&lt;p&gt;2. Launch cake module script as follows:&lt;/p&gt;
&lt;pre class=&quot;brush: bash; first-line: 1; gutter: false; tab-size: 4; toolbar: false; &quot;&gt;./cake.sh module schema -name sample_module&lt;/pre&gt;
&lt;p&gt;The module script creates files &lt;code&gt;config/sql/schema.php&lt;/code&gt; and &lt;code&gt;config/sql/mysql_schema.sql&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;3. Check &lt;code&gt;config/sql/mysql_schema.sql&lt;/code&gt; and if it&#039;s not correct, overwrite it with sql creation script that you used at step one. Cake schema can lose some table information, like constraints, that&#039;s why you could need to overwrite it with your original sql script.&lt;/p&gt;
&lt;p&gt;It&#039;s done! You can plug-in/plug-out your new pluginModule from BEdita Administration Plugin Module Section.&lt;/p&gt;</description><pubDate>Mon, 08 Feb 2010 11:59:28 +0100</pubDate><link>http://docs3.bedita.net/core/bedita-module-as-a-cakephp-plugin</link><guid>http://docs3.bedita.net/core/bedita-module-as-a-cakephp-plugin</guid></item><item><title>How to manage free semantic relations</title><description>Define and customize relations between BEdita objects&lt;hr/&gt;&lt;p&gt;Define and customize relations between BEdita objects&lt;/p&gt;&lt;hr/&gt;&lt;p&gt;One of the most powerful features of &lt;strong&gt;BEdita&lt;/strong&gt; is the possibility to define and use &lt;em&gt;free semantic relations between objects&lt;/em&gt;. In this article I&#039;m going to show you how build and use them.&lt;/p&gt;
&lt;h1&gt;BEdita objects&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;BEdita is completely object-oriented, &lt;/strong&gt;so every element is an object with a specific &lt;strong&gt;object type&lt;/strong&gt;. The object type itself defines some particular behaviors like the possibility to be showed in a certain module, the possibility to stay in the tree structure and the way to relate with other object types. You can find the BEdita object types inside the table &lt;strong&gt;object_types&lt;/strong&gt; that contains &lt;em&gt;id&lt;/em&gt;, &lt;em&gt;name&lt;/em&gt; and &lt;em&gt;module&lt;/em&gt; fields. To create a new relations we&#039;ll use the &lt;em&gt;id&lt;/em&gt; of the object types.&lt;/p&gt;
&lt;h1&gt;Where do I define relations between objects?&lt;/h1&gt;
&lt;p&gt;The first thing to know is that these relations have to be defined in a configuration file, in particular in &lt;code&gt;bedita-app/config/bedita.cfg.php&lt;/code&gt;. You can find some default relations in &lt;code&gt;bedita-app/config/bedita.ini.php&lt;/code&gt; but this file shouldn&#039;t be touched (may be overwritten during an update of BEdita), so have a look at the relations in this file only as reference.&lt;/p&gt;
&lt;p&gt;In &lt;code&gt;bedita.cfg.php&lt;/code&gt; you can find the configuration variable:&lt;/p&gt;
&lt;pre class=&quot;brush: php; first-line: 1; gutter: false; tab-size: 4; toolbar: false; &quot;&gt;$config[&quot;objRelationType&quot;] &lt;/pre&gt;
&lt;p&gt;commented. Uncomment it and let&#039;s customize your relations.&lt;strong&gt;&lt;br /&gt;Choose a name&lt;/strong&gt; for your relations for example &lt;em&gt;&quot;speakers&quot;&lt;/em&gt;:&lt;/p&gt;
&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;$config[&quot;objRelationType&quot;] = array(
   &quot;speakers&quot; =&amp;gt; array()
);&lt;/pre&gt;
&lt;p&gt;In this way I&#039;m going to define a free relation named &lt;em&gt;&quot;speakers&quot;&lt;/em&gt; that can link all objects. Now go to &lt;strong&gt;Addressbook&lt;/strong&gt; module (this module use Card objects, as you can see in object_types table) and click on create &lt;em&gt;&quot;new card&quot;&lt;/em&gt;. Have a look at &lt;strong&gt;Relationship tab&lt;/strong&gt; and you can see that the new relation appears in it (&lt;em&gt;figure 1&lt;/em&gt;).&lt;br /&gt;&lt;br /&gt;Now you can click on &lt;em&gt;&quot;Connect new items&quot;&lt;/em&gt; button to link other objects to this one, change order of related objects by drag &amp;amp; drop (&lt;em&gt;figure 2&lt;/em&gt;) and then save the card to estabilish the relation.&lt;/p&gt;
&lt;p&gt;In this way we have defined the relation for all object types so if you look at other modules like Documents, Events, Galleries, etc... you&#039;ll find the &lt;em&gt;&quot;speakers&quot;&lt;/em&gt; relation in the &lt;strong&gt;Relationship tab&lt;/strong&gt;. But if I want that the relation is estabilished only between some objects, how can I do it?&lt;/p&gt;
&lt;h1&gt;Customizing a relation between some object types&lt;/h1&gt;
&lt;p&gt;Suppose that I have to manage a festival site. I can create all festival events thorugh &lt;strong&gt;Events module&lt;/strong&gt; and all people that partecipate to the festival through &lt;strong&gt;Addressbook module&lt;/strong&gt;. Some of this people will be speakers so I will have to associate the events to the cards of the speakers through the &lt;em&gt;&quot;speakers&quot;&lt;/em&gt; relation. I want to use my &lt;em&gt;&quot;speakers&quot;&lt;/em&gt; relation only to link events to cards, I don&#039;t want to see and to use this relation in Galleries module, for instance. Edit &lt;code&gt;$config[&quot;objRelationType&quot;]&lt;/code&gt; in this way:&lt;/p&gt;
&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;$config[&quot;objRelationType&quot;] = array(
   &quot;speakers&quot; =&amp;gt; array(
      &quot;left&quot; =&amp;gt; array(&quot;card&quot;),
      &quot;right&quot; =&amp;gt; array(&quot;event&quot;)
   )
);&lt;/pre&gt;
&lt;p&gt;Here I define that the &lt;em&gt;&quot;speakers&quot;&lt;/em&gt; relation is estabilished between some object types. On the left I have card objects and on the right I have event objects. Note that the order of the object types in &lt;em&gt;&quot;left&quot;&lt;/em&gt;, &lt;em&gt;&quot;right&quot;&lt;/em&gt; key is indifferent.&lt;br /&gt;&lt;br /&gt;In this way only in Events and Addressbook mdoules you can see &lt;em&gt;&quot;&lt;/em&gt;&lt;em&gt;speakers&lt;/em&gt;&lt;em&gt;&quot;&lt;/em&gt; in &lt;strong&gt;Relationship tab&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;If you want to use this relation for other object types it&#039;s enough add &lt;em&gt;ids&lt;/em&gt; to &lt;em&gt;&quot;left&quot;&lt;/em&gt; or &lt;em&gt;&quot;right&quot;&lt;/em&gt; key so, for example:&lt;/p&gt;
&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;$config[&quot;objRelationType&quot;] = array(
   &quot;speakers&quot; =&amp;gt; array(
      &quot;left&quot; =&amp;gt; array(&quot;card&quot;),
      &quot;right&quot; =&amp;gt; array(&quot;event&quot;,&quot;documents&quot;)
   )
);&lt;/pre&gt;
&lt;p&gt;With this definition I can associate documents and events from a card object and I can associate only cards from a document or an event object.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h1&gt;One way relations&lt;/h1&gt;
&lt;p&gt;The relations are built in both directions by default, so I can see the association from both the objects involved. In some rare case I could desire that the relation were shown only in one direction. In these cases we can build a one way relation always editing &lt;code&gt;bedita.cfg.php&lt;/code&gt; file.&lt;/p&gt;
&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;$config[&quot;cfgOneWayRelation&quot;] = array(
   &quot;speakers&quot;, 
   &quot;other one way relation&quot;
);&lt;/pre&gt;
&lt;p&gt;Now if I create a &lt;em&gt;&quot;speakers&quot;&lt;/em&gt; relation from card to event I will see the relation inside the card object but I will not see it inside the event object.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h1&gt;Relations in frontend&lt;/h1&gt;
&lt;p&gt;As explained in &lt;a href=&quot;http://bedita.com/bedocs/il-primo-frontend&quot;&gt;&quot;My first frontend&quot;&lt;/a&gt; you&#039;ll find the semantic relations between objects in an &lt;strong&gt;array named&lt;/strong&gt; &lt;strong&gt;&quot;relations&quot;&lt;/strong&gt; so for example in an event related with some card by &lt;em&gt;&quot;speakers&quot;&lt;/em&gt; relation I will have:&lt;/p&gt;
&lt;pre class=&quot;brush: php; first-line: 1; tab-size: 4; toolbar: false; &quot;&gt;[relations] =&amp;gt; Array (
[speakers] =&amp;gt; array( 
   0 =&amp;gt; card1, 
   1 =&amp;gt; card2, 
   ...
)&lt;/pre&gt;
&lt;h2&gt;At the end&lt;/h2&gt;
&lt;p&gt;At the end of this article you should be able to build your custom semantic relations between objects in simple or complex way to model your &lt;strong&gt;BEdita&lt;/strong&gt; instance according to your needs.&lt;/p&gt;</description><pubDate>Fri, 29 May 2009 18:08:58 +0200</pubDate><link>http://docs3.bedita.net/core/how-manage-free-semantic-relations</link><guid>http://docs3.bedita.net/core/how-manage-free-semantic-relations</guid></item></channel></rss>