Today I had the problem of many people (believing forum posts left unanswered for years) :
How can I replace the code that runs behind a template operator, to avoid override all my templates?
How can I trigger this operator substitution directly from another operator, live in the template? (like an on / off switch...)
How to have absolute URLs in all templates calling "ezurl" without modifying the template code?!?
the small template developer
I finally have the answer! A technical solution that does not change anything in the kernel, which can be done in a small independent extension and which does not break ANYTHING until you have decided to activate the operator substitution! It's clean, it's fast, a little "on" at the beginning of the template, a little "off" at the end to clean, and all templates that will be called between them will use your own operator code!
The principle is simple (at first): simply declare (registerOperators) an operator that has the same name as the one that wants to replace ... Easy ... but as a simple solution does not always work (depending on the order in which extensions are loaded, and therefore WHO has the last word on the declaration of the operator ...), it's about making a register live in the template (switch to "on": to force dynamic declaration). It is also possible to reverse the process to return to the native operator. This gives the following code:
BEFORE : {'/user/login'|ezurl()} {* relative url... *}
WITH SUBSTITUTION :
{sethacks()}... {* switch on substitution *}
{'/user/login'|ezurl()} {* absolute url, or custom result *}
{unsethacks()}... {* switch off substitution *}
AFTER : {'/user/login'|ezurl()} {* relative url again... *}Just between sethacks() and unsethacks(), I call any full view of my content, and the template operator (ezurl in my example) is the one I have recoded in my extension!
Suppose you can do an extension with template operators (if you cannot, lean on known examples, as ezwebin ...).
In your eztemplateautoload.php file, you will get this :
$eZTemplateOperatorArray = array(); $eZTemplateOperatorArray[] = array( 'script' => 'extension/my_extension/autoloads/hackedoperators.php', 'class' => 'HackedOperators', 'operator_names' => array( 'sethacks' // NOTHING MORE HERE !!! ) );
You'll notice here, I do declare only a single operator, which allows the switch to initiate the process...
in your template operators file (hackedoperators.php for example), you will get this :
class HackedOperators {
function HackedOperators() {
$this->Operators = array(
'sethacks', 'unsethacks',
'ezurl' // HERE, FULL DECLARATION !
);
$this->NamedOperators = array(
'sethacks'=> array( ),
'unsethacks'=> array( ),
'ezurl'=> array(
'quote' => array( 'type'=>'string',
'required'=>false,'default'=>"double"),
'type' => array( 'type'=>'string',
'required'=>false,'default'=>"full"),
)
);
}
function modify($tpl, $operatorName, $operatorParameters,
$rootNamespace, $currentNamespace, &$operatorValue,
$namedParameters) {
switch ( $operatorName ) {
case 'sethacks':
$tpl->registerOperators($this); // force set for all ops
break;
case 'unsethacks':
$tpl->registerOperators(new eZURLOperator()); // reset ops
// complete here with all reset instructions
break;
case 'ezurl':
$this->ezurl($operatorValue, $namedParameters);
break;
default :
$tpl->warning( $operatorName, "Unknown operator" );
break;
}
}
function ezurl(&$value, $namedParameters) {
// HERE, PUT YOUR NEW EZURL CODE.
}
function operatorList() {
return $this->Operators;
}
function namedParameterPerOperator() {
return true;
}
function namedParameterList() {
return $this->NamedOperators;
}
}That's it!
Enjoy.
Labels provide the questions that forms ask people. Input fields give people a way to answer those questions. Neither ofMany pages in the admin interface have lots of form buttons. Currently they are either:
these items, however actually lets people complete a form. That
singular responsibility rests with actions.
| Colour | Meaning | Examples |
| Blue | Main Function | Send for publishing, Store Draft, Discard draft |
| Dark Grey | Supplementary Function | Add object, Disable Editor |
| Light Grey | Disabled | Remove Object (Related Object attribute where there's not an existing association) |
Buttons in the admin interface should be of a different colour depending on the action they trigger. For instance cancel buttons can be orange, publish buttons blue, remove buttons red, ... The main key here is to be consistent over all the interface.This was also added to the specification (#1 as a "Could").
JVMonitoring is a simple monitoring extension allowing you to check your application health through HTTP.

I have noticed in the past few months an explosion of new media sites built using eZ Flow. What is eZ Flow you may ask? In short, it is an extension created for the eZ Publish Enterprise Open Source Content Management System. The eZ Flow extension enables editors to build complex page layouts and pre-plan the publication schedule to ensure a constant flow of rich content. eZ Flow brings modern portal management possibilities to eZ Publish.
A overview of user task need a dashboard, where she can follow here own content, approval and other tasks she might do on a regular basis.
OpenSocial defines a common API for social applications across multiple websites. With standard JavaScript and HTML,Google personal home page is an example of an OpenSocial dashboard but basically there are 2 parts the gadget consumer/container (dashboard) and the gadget producer (the gadgets themselves),
developers can create apps that access a social network's friends and update feeds.
Each time a common module is called (like "content" or other simple modules, like AJAX ones), and so every time a content page, or an AJAX module in an extension is called our dear kernel (/index.php) updates a session variable called: LastAccessesURI.
This variable is used when leaving edit mode, to return to the previous page, or when a log is finished, to return to the URL that was requested before having to log ...
This is annoying because chronologically, when a person displays a page in the front office containing an AJAX call to an eZpublish extension, these steps are followed:
So, because the last request to eZpublish is an AJAX one, to an AJAX module, the wrong URI will be used when the user exits from edit mode, or is redirected after a successful /user/login, (or another module using LastAccessesURI variable), and then, the user is redirected to the AJAX module in full view, which is not the last page the user saw.
Fortunately, eZpublish is great (when you read directly the kernel code): we can declare our module in a particular way to prevent the LastAccessesURI variable to be updated. In the kernel, in index.php, a condition protects an update to the LastAccessesURI variable:
if ( ... && !in_array( $module->uiContextName(),
array('edit','administration','browse','authentication')
)) {
$http->setSessionVariable("LastAccessesURI",
$currentURI);
}So now, you can redeclare your AJAX module like an admin module, and that's all!
In your extension/.../modules/.../module.php, use the following code:
$ViewList['get'] = array(
'script' => 'get.php',
'ui_context' => 'administration'
);
Regarding to a recent post I put here about Kerberos and Apache, there is a way to replace Kerberos when the Active Directory cannot be properly configured to accept Kerberos connections. You can simulate the NTLM auth process with the browser by 6 steps in PHP :
function get_login() {
/*
step: | type:
-------|----------------|------------------------------------
1 | C --> S | GET ...
-------|----------------|------------------------------------
2 | C <-- S | 401 Unauthorized
| | WWW-Authenticate: NTLM
-------|----------------|------------------------------------
3 | C --> S | GET ...
| | Authorization: NTLM
| | <base64-encoded type-1-message>
-------|----------------|------------------------------------
4 | C <-- S | 401 Unauthorized
| | WWW-Authenticate: NTLM
| | <base64-encoded type-2-message>
-------|----------------|------------------------------------
5 | C --> S | GET ...
| | Authorization: NTLM
<base64-encoded type-3-message>
-------|----------------|------------------------------------
6 | C <-- S | 200 Ok
-------|----------------|------------------------------------
*/
$headers = apache_request_headers();
if($headers['Authorization'] == NULL) { // step 1
header( "HTTP/1.1 401 Unauthorized" ); // step 2
header( "WWW-Authenticate: NTLM" );
exit;
};
if(isset($headers['Authorization'])
&& substr($headers['Authorization'],0,5) == 'NTLM ') {
// step 3 to 6
$chaine=$headers['Authorization'];
$chaine=substr($chaine, 5); // type1 message
$chained64=base64_decode($chaine);
if(ord($chained64{8}) == 1) { // step 3
// check NTLM flag "0xb2",
// offset 13 in type-1-message :
if (ord($chained64[13]) != 178) {
echo "Please use NTLM compatible browser";
return null;
}
$retAuth = "NTLMSSP";
$retAuth .= chr(0).chr(2).chr(0).chr(0);
$retAuth .= chr(0).chr(0).chr(0).chr(0);
$retAuth .= chr(0).chr(40).chr(0).chr(0);
$retAuth .= chr(0).chr(1).chr(130).chr(0);
$retAuth .= chr(0).chr(0).chr(2).chr(2);
$retAuth .= chr(2).chr(0).chr(0).chr(0);
$retAuth .= chr(0).chr(0).chr(0).chr(0);
$retAuth .= chr(0).chr(0).chr(0).chr(0).chr(0);
$retAuth64 =base64_encode($retAuth);
$retAuth64 = trim($retAuth64);
header( "HTTP/1.1 401 Unauthorized" ); // step 4
header( "WWW-Authenticate: NTLM $retAuth64" );
exit;
}
else if(ord($chained64{8}) == 3) { // step 5
$lenght_domain = (ord($chained64[31])*256 + ord($chained64[30]));
$offset_domain = (ord($chained64[33])*256 + ord($chained64[32]));
$domain = substr($chained64, $offset_domain, $lenght_domain);
$lenght_login = (ord($chained64[39])*256 + ord($chained64[38]));
$offset_login = (ord($chained64[41])*256 + ord($chained64[40]));
$login = substr($chained64, $offset_login, $lenght_login);
$lenght_host = (ord($chained64[47])*256 + ord($chained64[46]));
$offset_host = (ord($chained64[49])*256 + ord($chained64[48]));
$host = substr($chained64, $offset_host, $lenght_host);
}
}
$login = preg_replace("/(.)(.)/","$1",$login);
$domain = preg_replace("/(.)(.)/","$1",$domain);
$login = strtolower($login);
$domain = strtoupper($domain);
return array($login,$domain); // step 6 : accept
}
Warning : this code must be exectuted not only for the auth process when you want to login the user, but for each HTTP request to your application (so on each page).
It is very important to put HTTP 1.1 protocole in HTTP headers because HTTP 1.0 does not support Keep-alive connection and so NTLM auth. For some unknown reasons, even if some Apache versions change automatically the protocole version to 1.1 in your headers, other versions don't (for example 2.2.3 can do it and 2.2.9 can't).
Finally, keep in mind that this code is not as secure as Kerberos Apache module, because this code will never check Active Directory permission to accept the user. This function is just to retrieve login and domain, you have to make the account check yourself.
Good luck !
After few months developing a little try under Android API, I wanted to make feedback on benefits of the Google OS. I want to achieve the first version of my project and then make a constructive criticism about Android regarding to other graphical or mobile APIs, like the iPhone.
Since the beginning of the year, I established a personal project to develop a small Android application, quite independent, using GUI at maximum of its capacities, a database (SQLite) and a few onboard Google Maps onboard. I'll give small screenshots in a way that says enough along on the usefulness of the program, because I do not know yet exactly what I will do with my application.
My first impressions over development were: