PHP PROGRAMMING PATTERN FOR THE PREFERENCES USABILITY MECHANISM Drafted by Francy Diomar Rodríguez, Software and Systems PhD Student, Facultad de Informática. Universidad Politécnica de Madrid. (fd.rodriguez@alumnos.upm.es) Content 1 Introduction... 1 2 Preferences UM design pattern... 1 3 Preferences UM Pattern (PHP - JQuery)... 2 1 Introduction This document presents an implementation-oriented design pattern and the respective programming pattern developed in PHP for the Preferences usability mechanism (UM). 2 Preferences UM design pattern This is a design pattern for implementing the Preferences usability mechanism. The Solution section details the responsibilities that the usability functionality has to fulfil. The Structure section contains the proposed design and the Implementation section describes the steps necessary for codifying the proposed design. NAME PROBLEM CONTEXT Preferences UM Implement the Preferences um pattern for web applications so that some application features can be tailored to user preferences. Highly complex, interactive web applications for use by users with different skills, cultures and tastes. SOLUTION Components are required to fulfil the responsibilities associated with the UM. They are: A persistence mechanism for the preference types that can be set in the application, for example, language, fonts (family and size), color and so on. A persistence mechanism for the preferences that save the different combinations of preferences types: basic configuration, default settings and user custom settings. A component that allows to applied a set of preferences to the application in any time. Adapt application pages in order to define dinamically its style file.css using the PreferencesCSS class, in this way the configuration values will be always applied when the page is loaded. A component to show to the user his o her current preferences configuration and allow change its values. A component that allows seen the set of established configurations and that the user can choice one of them in order to change the current configuration. A component to that the user can change the current language of the application. STRUCTURE
IMPLEMENTATIÓN 1. Create a persistence mechanism for the information on configurable application preference types. The information to be stored by this component is: id (mechanism type identifier) and name. A means of data object access should be created for querying, creating, deleting and updating this information. 2. Create a persistence mechanism for the information on basic, predefined or personalized preferences sets. There must be a means of data object access for querying, creating, deleting and updating this information. The information to be updated by this component is: id_set (preference set identifier), id_preference_type (configurable feature identifier), name (name of the preference type attribute, if any), is_default (specifies whether the configuration is predefined), and value (the value of the configuration). 3. Implement a PreferencesCSS class that is able to generate the application style sheet dynamically by reading the configuration parameters. In the load pages call the PreferencesCSS class with the user configuration id in order to create the style file.css and the style can be applied to the page Create a page that displays the current preferences settings so that users can change their values. 4. Create a page that displays all the predefined preferences settings to be selected by users to change their current settings. 5. Create options (always visible) in order to change the application language at application level. The properties or resource files containing the translations of titles and labels to the target languages must be created beforehand. RELATED Facade pattern and MVC pattern. PATTERNS 3 Preferences UM Pattern (PHP - JQuery) Programming patterns specify the details of the implementation using a specific language. They offer either a standalone solution or describe how to implement particular aspects of the components of a design pattern using the programming language features and potential. The 2
Solution section describes the steps necessary for codification and is equivalent to the Implementation section of the design pattern. The Structure section shows the design tailored for the PHP language and the Example section shows the PHP code for each step of the solution. NAME PROBLEM CONTEXT Preferences UM ((PHP - JQuery) Implement the Preferences UM pattern for web applications built in PHP with JQuery so that some application features can be tailored to user preferences. Highly complex, interactive web applications for use by users with different skills, cultures and tastes. SOLUTIÓN 1. Create a persistence mechanism for the information on configurable application preference types. The information to be stored by this component is: id (mechanism type identifier) and name. A means of data object access should be created for querying, creating, deleting and updating this information. 2. Create a persistence mechanism for the information on basic, predefined or personalized preferences sets. There must be a means of data object access for querying, creating, deleting and updating this information. The information to be updated by this component is: id_set (preference set identifier), id_preference_type (configurable feature identifier), name (name of the preference type attribute, if any), is_default (specifies whether the configuration is predefined), and value (the value of the configuration). 3. Implement a PreferencesCSS class that is able to generate the application style sheet dynamically by reading the configuration parameters. In the load pages call the PreferencesCSS class with the user configuration id in order to create the style file.css and the style can be applied to the page Create a page that displays the current preferences settings so that users can change their values. 4. Create a page that displays all the predefined preferences settings to be selected by users to change their current settings. 5. Create options (always visible) in order to change the application language at application level. The properties or resource files containing the translations of titles and labels to the target languages must be created beforehand. STRUCTURE EXAMPLE 3
Create a persistence mechanism for the information on configurable application preference types. The information to be stored by this component is: id (mechanism type identifier) and name. A means of data object access should be created for querying, creating, deleting and updating this information. Primero se debe crear una tabla en la base de datos Preference_type, Se utiliza un patrón DAO para acceder a los datos, entonces se crean los componentes VO y DAO, dado que en este caso la información se devuelve en formato XML se requiere un componente adicional para construirlo que se denomina RESULT. Este es el VO: class PreferenceType { public $id; public $name; public function set($id, $name) { $this->id = $id; $this->name = $name; public function getelement($elementparent, $dom) { $element = $elementparent->appendchild($dom->createelement("preferencetype")); $element->setattribute('id', $this->id); $element->setattribute('name', utf8($this->name)); return $element; class PreferenceTypeDAO { public function listall() { $list = new ArrayObject(); $sql = "SELECT id, name FROM preference_type"; $rows = $db->query($sql); foreach ($rows as $row) { $item = new PreferenceType(); $item->set($row->id, $row->name); $list->append($item); return $list; public function find($id) { $sql = "SELECT id, name FROM preference_type WHERE id='$id'"; $register = $db->find($sql); $item = new PreferenceType(); $item->set($register->id, $register->name); return $item; class PreferenceTypeResult extends Result { parent:: construct(); // MEtodo de ejecución public function execute($operation) { switch ($operation) { case "list": $this->listall($this->dom, $this->root); case "find": $this->find($this->dom, $this->root, $_REQUEST["id"]); 4
default: throw new Exception("Operación '". $operation. "' no implementada para un Tipo de Preferencia.", 200); public function listall($dom, $root) { $dao = new PreferenceTypeDAO(); $rows = $dao->listall(); $rowselement = $root->appendchild($dom->createelement("preferencetypes")); foreach ($rows as $row) $row->getelement($rowselement, $dom); public function find($dom, $root, $id) { $dao = new PreferenceTypeDAO(); $item = $dao->find($id); return $item->getelement($root, $dom); Create a persistence mechanism for the information on basic, predefined or personalized preferences sets. There must be a means of data object access for querying, creating, deleting and updating this information. Primero se debe crear una tabla en la base de datos Preference, Se utiliza un patrón DAO para acceder a los datos, entonces se crean los componentes VO, DAO y RESULT. class Preference { public $idset; public $idpreferencetype; public $name; public $default; public $value; public function set($idset, $idpreferencetype, $name, $default, $value) { $this->idset = $idset; $this->idpreferencetype = $idpreferencetype; $this->name = $name; $this->default = $default; $this->value = $value; public function getelement($elementparent, $dom) { $element = $elementparent->appendchild($dom->createelement("preference")); $element->setattribute('idset', $this->idset); $element->setattribute('name', utf8($this->name)); $element->setattribute('default', $this->default); $preference = new PreferenceTypeResult(); $preference->find($dom, $element, $this->idpreferencetype); $elementvalue = $element->appendchild($dom->createelement("value")); $elementvalue->appendchild($dom->createtextnode(utf8($this->value))); return $element; class PreferenceDAO { 5
public function listall() { $list = new ArrayObject(); $sql = "SELECT id_set, id_preference_type, name, `default`, value FROM preference"; $rows = $db->query($sql); foreach ($rows as $row) { $item = new Preference(); $item->set($row->id_set, $row->id_preference_type, $row->name, $row->default, $row->value); $list->append($item); return $list; public function findset($idset) { $list = new ArrayObject(); $sql = "SELECT id_set, id_preference_type, name, `default`, value FROM preference WHERE id_set=$idset"; $rows = $db->query($sql); foreach ($rows as $row) { $item = new Preference(); $item->set($row->id_set, $row->id_preference_type, $row->name, $row->default, $row->value); $list->append($item); return $list; public function isdefaultset($idset) { $sql = "SELECT count(*) AS counted FROM preference WHERE `default`=1 AND id_set=$idset"; $row = $db->find($sql); return $row->counted > 0; public function nextidset() { $sql = "SELECT max(id_set)+1 AS next FROM preference"; $row = $db->find($sql); return $row->next; public function find($idset, $idpreferencetype, $name) { $sql = "SELECT id_set, id_preference_type, name, `default`, value FROM preference WHERE id_set=$idset AND id_preference_type=$idpreferencetype AND name='$name'"; $row = $db->find($sql); $item = new Preference(); $item->set($row->id_set, $row->id_preference_type, $row->name, $row->default, $row->value); return $item; public function insert($idset, $idpreferencetype, $name, $default, $value) { $sql = "INSERT INTO preference (id_set, id_preference_type, name, `default`, value) "; $sql.= "VALUE ($idset, $idpreferencetype, '$name', '$default', '$value')"; return $db->insert($sql); public function delete($idset, $idpreferencetype, $name) { $sql = "DELETE FROM preference WHERE id_set=$idset AND id_preference_type=$idpreferencetype AND name='$name'"; $db->delete($sql); 6
public function update($idset, $idpreferencetype, $name, $default, $value) { $sql = "UPDATE preference "; $sql.= "SET `default` = '$default', value='$value' "; $sql.= "WHERE id_set=$idset AND id_preference_type=$idpreferencetype AND name='$name'"; $db->update($sql); class PreferenceResult extends Result { parent:: construct(); // MEtodo de ejecución public function execute($operation) { switch ($operation) { case "list": $this->listall($this->dom, $this->root); case "findset": $this->findset($this->dom, $this->root, $_REQUEST["idSet"]); case "edit": $this->edit($this->dom, $this->root, $_REQUEST["idSet"], $_REQUEST["idPreferenceType"], $_REQUEST["name"]); case "create": $this->create($this->dom, $this->root); case "insert": $this->insert($this->dom, $this->root, $_REQUEST["preference"]); case "delete": $this->delete($_request["preference"]); case "update": $this->update($this->dom, $this->root, $_REQUEST["preference"]); default: throw new Exception("Operación '". $operation. "' no implementada para un Preferencia.", 300); public function listall($dom, $root) { $rows = $dao->listall(); $rowselement = $root->appendchild($dom->createelement("preferences")); foreach ($rows as $row) $row->getelement($rowselement, $dom); public function findset($dom, $root, $idset) { $rows = $dao->findset($idset); $rowselement = $root->appendchild($dom->createelement("preferences")); $rowselement->setattribute('idset', $idset); foreach ($rows as $row) $row->getelement($rowselement, $dom); public function edit($dom, $root, $idset, $idpreferencetype, $name) { $row = $dao->find($idset, $idpreferencetype, $name); $row->getelement($root, $dom); 7
$type = new PreferenceTypeResult(); $type->listall($dom, $root); public function create($dom, $root) { $type = new PreferenceTypeResult(); $type->listall($dom, $root); public function insert($dom, $root, $preference) { $dao->insert($preference["idset"], $preference["idpreferencetype"], $preference["name"], $preference["default"], $preference["value"]); public function insertset($dom, $root, $idset, $preferences) { //Se inserta aqui las diferentes preferencias $dao->insert($idset, 1, 'name', 0, $preferences["languagename"]); $dao->insert($idset, 2, 'family', 0, $preferences["fontfamily"]); $dao->insert($idset, 2, 'size', 0, $preferences["fontsize"]); $dao->insert($idset, 3, 'theme', 0, $preferences["schemetheme"]); $dao->insert($idset, 4, 'enable', 0, $preferences["soundenable"]); $dao->insert($idset, 4, 'wav', 0, $preferences["soundwav"]); $dao->insert($idset, 5, 'icon1', 0, $preferences["objecticono1"]); public function updateset($dom, $root, $idset, $preferences) { //Se inserta aqui las diferentes preferencias $dao->update($idset, 1, 'name', 0, $preferences["languagename"]); $dao->update($idset, 2, 'family', 0, $preferences["fontfamily"]); $dao->update($idset, 2, 'size', 0, $preferences["fontsize"]); $dao->update($idset, 3, 'theme', 0, $preferences["schemetheme"]); $dao->update($idset, 4, 'enable', 0, $preferences["soundenable"]); $dao->update($idset, 4, 'wav', 0, $preferences["soundwav"]); $dao->update($idset, 5, 'icon1', 0, $preferences["objecticono1"]); public function delete($idset, $idpreferencetype, $name) { $dao->delete($idset, $idpreferencetype, $name); public function update($dom, $root, $preference) { $dao->update($preference["idset"], $preference["idpreferencetype"], $preference["name"], $preference["default"], $preference["value"]); Implement a PreferencesCSS class that is able to generate the application style sheet dynamically by reading the configuration parameters. session_start(); header("content-type: text/css"); header("content-disposition: attachment; filename=preferences.css"); header("content-description: PHP Generated Data"); include "Utils.php"; 8
include "DAO/DBMySQL.php"; //Incluir VO's include "VO/PreferenceType.php"; include "VO/Preference.php"; include "VO/PreferencesSet.php"; include "VO/User.php"; //Incluir DAO's include "DAO/PreferenceTypeDAO.php"; include "DAO/PreferenceDAO.php"; include "DAO/UserDAO.php"; //Inluir RESPONSE's include "RESULT/Result.php"; include "RESULT/PreferenceTypeResult.php"; include "RESULT/PreferenceResult.php"; include "RESULT/UserResult.php"; //Punto de entrada de aplicación---------------------------------------- $set = new PreferencesSet(); $set->init($_request["idset"]); $set->write(); //----------------------------------------------------------------------?> //Para este caso se ha implementado una clase auxiliar PreferencesSet que facilita la generación del archivo css class PreferencesSet { public $preferences; private function findpreference($preferencetype, $name) { foreach ($this->preferences as $preference) if ($preference->idpreferencetype == $preferencetype && $preference->name == $name) return $preference->value; return null; public function themes($dom, $root) { $themeselement = $root->appendchild($dom->createelement("themes")); $path = "../css"; $dirs = dir($path); while (false!== ($dir = $dirs->read())) { if ($dir!= '.' && $dir!= '..' && is_dir($path. '/'. $dir)) { $themeelement = $themeselement->appendchild($dom->createelement("theme")); $themeelement->setattribute('name', $dir); $dirs->close(); public function init($idset) { try { $this->preferences = $dao->findset($idset); catch (Exception $e) { 9
$this->preferences = $dao->findset(0); public function write() { $theme = $this->findpreference(3, "theme"); include '../css/'. $theme. '/'. $theme. '.css';?> body { font-size : <?php echo $this->findpreference(2, "size");?>; font-family : <?php echo $this->findpreference(2, "family");?>; <?php?> In the load pages call the PreferencesCSS class with the user configuration id in order to create the style file.css and the style can be applied to the page Create a page that displays the current preferences settings so that users can change their values. <link type="text/css" rel="stylesheet" href="php/preferencescss.php?idset=<?php echo $idset;?>" /> Create a page that displays the current preferences settings so that users can change their values. Se crea llamando la correspondiente opción del PreferencesResult. Create a page that displays all the predefined preferences settings to be selected by users to change their current settings. Se crea llamando la correspondiente opción del PreferencesResult. Create options (always visible) in order to change the application language at application level. The properties or resource files containing the translations of titles and labels to the target languages must be created beforehand. 10