Je dévelope actuellement un composant qui permettra aux clients d'envoyer des messages anonymes à un groupe d'administrateur charger de s'occuper de ces gens.
J'ai suivi la docs officiel qui propose de crée un petit helloworld.
Premier problème le tri des colonnes dans la partie admin ne fonctionnait pas, j'ai reussi à résoudre ce probléme en farfouillant dans les composant joomla (com_banners)
J'ai ensuite voulu ajouter les filtres j'ai donc suivi ce tuto :http://docs.joomla.org/J2.5:How_to_a..._to_components
Que j'ai adapter à la version 3.x en utilisant encore une fois ce que j'ai pu voir dans com_banners.Cela ne fonctionne pas.
Le problème :
aprés l'ajout du code le tri ne fonctionne plus (on clique une fois ca tri en asc, on reclick ca trie en desc, on reclik encore ca remet en asc puis ca ne change plus)
Le probléme viens, je pense, du fullordering :
ma consol me dit : public 'list.fullordering' => string 'null ASC' (length=8)
Dans Admin/forms j'ai ajouter ceci a mon fichier xml :
Code HTML:
<fields name="list"> <field name="fullordering" type="list" label="JGLOBAL_SORT_BY" statuses="*,0,1,2,-2" description="JGLOBAL_SORT_BY" onchange="this.form.submit();" default="id ASC" > <option value="">JGLOBAL_SORT_BY</option> <option value="id ASC">JGRID_HEADING_ID_ASC</option> <option value="id DESC">JGRID_HEADING_ID_DESC</option> </field> <field name="limit" type="limitbox" class="input-mini" default="25" label="COM_ONLINEHELPS_LIST_LIMIT" description="COM_ONLINEHELPS_LIST_LIMIT_DESC" onchange="this.form.submit();" /> </fields>
Actuellement ma fonction populatestate ressemble a ceci :
Code PHP:
protected function populateState($ordering = null, $direction = null)
{
// Initialise variables.
$app = JFactory::getApplication('administrator');
// Load the filter state.
$search = $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search');
$this->setState('filter.search', $search);
$state = $this->getUserStateFromRequest($this->context . '.filter.state', 'filter_state', '', 'string');
$this->setState('filter.state', $state);
// Load the parameters.
$params = JComponentHelper::getParams('com_letest');
$this->setState('params', $params);
// List state information.
parent::populateState('id', 'asc');
}
Edit: après quelques manipulations sur le com_banners j'ai decouvert que mon problème ne vient pasdu fullordering je repars à 0
EDIT 07/10/14
J'ai reussi a faire fonctionner le tri avec les filtre par defaut de joomla (state et search) en revanche j'ai ajouter un nouveau filtre 'section' qui correspond a la colonne 'section' de ma table.Cette colonne peut contenir 3 valeurs (jeune / adulte / prof) l'idée c'est de pouvoir aficher que les lignes qui correspondent a jeune (par exemple) mais je bloque.
ma fonction getoption (admin/models/fields/monfichier.php):
Code PHP:
protected function getOptions()
{
// Initialize variables.
$options = array();
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('id As value, section As text')
->from('#__matable AS a')
->order('a.section');
// Get the options.
$db->setQuery($query);
$options = $db->loadObjectList();
// Check for a database error.
if ($db->getErrorNum()) {
JError::raiseWarning(500, $db->getErrorMsg());
}
return $options;
}
Code:
<field name="section" type="monfichier" label="COM_MONFICHIERS_FILTER_SECTION" description="COM_MONFICHIERS_FILTER_SECTION_DESC" onchange="this.form.submit();" > <option value="">COM_MONFICHIERS_SELECT_SECTION</option> </field>
Code PHP:
if ($section = $this->getState('filter.section'))
{
var_dump($this->getState('filter.section'));
$query->where('section = ' . $db->quote($section));
echo $query;
}
Les filtres fonctionnent j'ai crée un fichier php par filtre spécifiques pour les filtres 'globaux' j'ai pu utiliser les librairies joomla voiciun exemple d'un fonction getOptions() pour un filtre spécifique :
Code PHP:
protected function getOptions()
{
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select ('distinct section As value, section As text')
->from('#__matable AS a')
->group('value');
// Get the options.
$db->setQuery($query);
try
{
$options = $db->loadObjectList();
}
catch (RuntimeException $e)
{
JError::raiseWarning(500, $e->getMessage());
}
// Merge any additional options in the XML definition.
// $options = array_merge(parent::getOptions(), $options);
array_unshift($options, JHtml::_('select.option', '0', JText::_('COM_MONCOMPOSANT_SECTION')));
return $options;
}
}
Code PHP:
protected function populateState($ordering = null, $direction = null)
{
// List state information.
parent::populateState('id', 'asc');
}
{
// List state information.
parent::populateState('id', 'asc');
}
Pour mes filtres perso voilà ma démarche :
-ajout du field XML dans le fichier filter_tonfiltre.xml (admin/models/forms)
-ajout du filtre dans le fichier php toncomposants.php (admin/models) comme suit (exemple pour un filtre spécifique et un filtre qui utilise les lib joomla):
Code PHP:
// Filter by published state
$published = $this->getState('filter.published');
if (is_numeric($published))
{
$query->where('published = ' . (int) $published);
}
elseif ($published === '')
{
$query->where('(published IN (0, 1))');
}
//filter by section
if ($section = $this->getState('filter.section'))
{
$query->where('section = ' . $db->quote($section));
}
Code PHP:
<div class="row-fluid">
<div class="span12">
<?php echo JText::_('COM_ONLINEHELP_ONLINEHELPS_FILTER'); ?> <?php
echo JLayoutHelper::render(
'joomla.searchtools.default',
array('view' => $this)
);
?> </div>
</div>
Je m'attaque au coté client actuellement j'ai un formulaire de ce type :
Code HTML (la vue) :
<form id="form_oh" method="post" action="components\com_onlinehelp\controllers\formulaire.php"> <fieldset> <p><label for="pseudo">Ton pseudo :</label><input type="text" id="pseudo" name="pseudo" required /></p> <p><label for="genre">Tu es :</label> <input type="radio" id="genre_m" name="genre" /> un garçon</p> <input type="radio" id="genre_f" name="genre" /> une fille</p> <p><label for="age">Ton âge :</label><input type="number" id="age" name="age" required /></p> <p><label for="question">Ta question :</label><textarea id="question" name="question" required cols="30" rows="8"></textarea></p> Ici tu peux écrire le texte de ta demande. Tu peux nous écrire en français, en allemand, en anglais. Tu peux agrandir le champ texte en tirant avec le pointeur sur l'angle en bas à droite </fieldset> <div style="text-align:center;"><input type="submit" name="envoi" value="Envoyer ma question" /></div> </form>
Code PHP (controlleur):
if(isset($_POST['pseudo'])) $pseudo=$_POST['pseudo'];
else $pseudo="";
if(isset($_POST['genre'])) $genre=$_POST['genre'];
else $genre="";
if(isset($_POST['age'])) $age=$_POST['age'];
else $age="";
if(isset($_POST['question'])) $question=$_POST['question'];
else $question=""; // On vérifie si les champs sont vides if(empty($pseudo) OR empty($genre) OR empty($age) OR empty($question))
{
echo '<font color="red">Attention, tous les champs sont obligatoires !</font>';
}
l'idée c'est d'utiliser les outils joomla (genre Jinput) pour rendre le tout plus safe (pasque la bonjour les injections !)
Donc le frontend fonctionne voici les modif faite sur le code :
Ensuite voila a quoi ressemble mon fichier view.html.php :Code PHP (la vue):
<div class="composant-form">
<form id="composant-form" action="<?php echo JRoute::_('index.php'); ?>" method="post" class="form-validate form-horizontal">
<fieldset>
<legend><?php echo JText::_('COM_COMPOSANT_FORM_LABEL');?></legend>
<div class="control-group">
<div class="control-label"><?php echo $this->form->getLabel('section'); ?></div>
<div class="controls"><?php echo $this->form->getInput('section'); ?></div>
</div>
<div class="control-group">
<div class="control-label"><?php echo $this->form->getLabel('pseudo'); ?></div>
<div class="controls"><?php echo $this->form->getInput('pseudo'); ?></div>
</div>
<div class="control-group">
<div class="control-label"><?php echo $this->form->getLabel('genre'); ?></div>
<div class="controls"><?php echo $this->form->getInput('genre'); ?></div>
</div>
<div class="control-group">
<div class="control-label"><?php echo $this->form->getLabel('age'); ?></div>
<div class="controls"><?php echo $this->form->getInput('age'); ?></div>
</div>
<div class="control-group">
<div class="control-label"><?php echo $this->form->getLabel('question'); ?></div>
<div class="controls"><?php echo $this->form->getInput('question'); ?></div>
</div>
</fieldset>
<div class="form-actions">
<button class="btn btn-primary validate" type="submit"><?php echo JText::_('COM_COMPOSANT_COMPOSANT_SEND'); ?></button>
<input type="hidden" name="option" value="com_composant" />
<input type="hidden" name="task" value="composant.submit" />
<?php echo JHtml::_('form.token'); ?> </div>
</form>
</div>
Code PHP (view.html.php) il récupére le form et le passe à la vue ce qui permet de faire les traitements:
class OnlineHelpViewOnlineHelp extends JViewLegacy { // Overwriting JView display method
function display($tpl = null)
{
// Assign data to the view
$this->form = $this->get('Form');
// Check for errors.
if (count($errors = $this->get('Errors')))
{
JLog::add(implode('<br />', $errors), JLog::WARNING, 'jerror');
return false;
}
// Display the view
parent::display($tpl);
}
}
Ensuite j'ai eu besoin de crée une page qui, aprés l'envoi du formulaire, affiche un message de confirmation ainsi que le pseudo et un code unique pour l'utilisateur, j'ai donc du recup les données.La première idée fu de passer mes 2 param dans l'url et de les recupéré avec un $_GET, cette variable n'étant pas 'safe' le Jinput fait son retour :
pour pouvoir utiliser tout correctement et surtout proprement j'ai crée 2 fonctions dans mon model :
Code PHP (confirmation.php : le model) :
/**
* Get the pseudo
* @return string The pseudo to be displayed to the user
*/
public function getPseudo()
{
$jinput = JFactory::getApplication()->input;
if (!isset($this->pseudo))
{
$this->pseudo = $jinput->get('pseudo');
}
return $this->pseudo;
}
/**
* Get the code question
* @return string The code unique to be displayed to the user
*/
public function getCode_unique()
{
$jinput = JFactory::getApplication()->input;
if (!isset($this->code_unique))
{
$this->code_unique = $jinput->get('code_unique');
}
return $this->code_unique;
}
Ensuite j'ai rajouter la génération d'un code unique dans mon tableau de donnée que je crée dans mon controllers dans ma fonction submit:
Code PHP:
$data[code_question] = uniqid();
Ainsi a la fin de mon submit je redirige vers une URL qui contient mes 2 valeurs :
Ensuite on assigne nos données a la vue (via le fichier view.html.php de notre vue 'confirm)Code PHP:
$this->setRedirect(JRoute::_('index.php?option=com_composant&view=confirm&pseudo='.$data[pseudo].'&code_unique='.$data[code_question],false));
Code PHP (view.html.php):
class ComposantViewConfirm extends JViewLegacy { // Overwriting JView display method
function display($tpl = null)
{
// Assign data to the view
$this->pseudo = $this->get('Pseudo');
$this->code_question = $this->get('Code_unique');
// Check for errors.
if (count($errors = $this->get('Errors')))
{
JLog::add(implode('<br />', $errors), JLog::WARNING, 'jerror');
return false;
}
// Display the view
parent::display($tpl);
}
}
On peut donc utiliser notre pseudo et notre code unique sans soucis dans la vue (et surtout sans $_GET et de manière sécurisée)
(les longue chaine de majuscules sont des label, j'utilise un fichier de traduction il n'y a donc aucun texte en dur dans le code)Code PHP:
<p><?php echo JText::_('COM_COMPOSANT_MSG_CONFIRMATION_PSEUDO'); echo $this->pseudo ; ?></p>
<p><?php echo JText::_('COM_COMPOSANT_MSG_CONFIRMATION_CODE_UNIQUE'); echo $this->code_unique; ?></p>
Aller on attaque la création du module !
J'attaque la création du module lié à ce composant, j'ai crée un suivi de la même manière disponible ici: http://nep-dev.blogspot.com/2014/10/joomla-suivi-de-creation-de-module-3x.html
RépondreSupprimer