|
13 Červenec 2010
Posted in
Články -
Tipy a triky
Jestli jste již zkoušeli připravovanou Joomlu 1.6, tak jste si určitě všimnuli, že v nastavení modulů si lze vybrat položky menu, kde se nemá daný modul zobrazovat. Což oproti současnému stavu, kdy lze vybrat pouze položky menu u kterých se má modul zobrazovat přináší výhodu, že nemusíme po každém přidání nové položky upravovat nastavení modulů, aby se zobrazovaly i u nové vzniklé položky menu. Přesně takovou funkci si do stávající Joomly 1.5 dneska přidáme.
Příprava
Budeme k tomu potřebovat úpravu čtyř souborů a jednu novou tabulku v databázi. Tabulku vytvoříme pomocí SQL příkazu:
CREATE TABLE #__modules_menu_exclude (moduleid int(11) NOT NULL DEFAULT '0', menuid int(11) NOT NULL DEFAULT '0', PRIMARY KEY(moduleid,menuid));
#__ nahradíme za prefix tabulek Joomly. Nejčastěji se bude jednat o jos_. Když se podíváme do tabulek Joomly zjistíme, přiřazení modulů k nabídkám Joomly se děje pomocí tabulky #__modules_menu, která může obsahovat dva typy hodnot. Pokud se má modul zobrazovat u všech položek menu, tak se v poli menuid nachází hodnota 0, jinak ID položek menu u kterých se má daný modul zobrazit. Pro naší úpravu se jako nejvhodnější jeví do pole menuid uložit hodnotu -1 a do nové tabulky #__modules_menu_exclude ID položek menu, u kterých se daný modul nemá zobrazovat.
Administrace
S úpravami začneme v administraci, kde potřebujeme upravit dva soubory - controller.php a admin.modules.html.php (pozornějšímu čtenáři jistě neunikne, že administrace Joomly ještě plně nevyužívá vzoru MVC). Jako první upravíme controller.php a to funkci edit(), která načítá data pro editační formulář. Kolem řádku 443 najdeme SQL dotaz načítající ID menu z tabulky #__modules_menu a o několik řádků níže podmínku, kterou potřebujeme upravit do následujícího tvaru:
if (empty( $lookup )) { $lookup = array( JHTML::_('select.option', '-1' ) ); $row->pages = 'none'; } elseif (count($lookup) == 1 && $lookup[0]->value == 0) { $row->pages = 'all'; // Start of addition by Filip Bartmann, http://joomladev.eu } elseif(count($lookup) == 1 && $lookup[0]->value == -1) { $row->pages='exclude'; $query="SELECT menuid AS value \n"; $query.="FROM #__modules_menu_exclude \n"; $query.="WHERE moduleid=".(int) $row->id; $db->setQUery($query); $lookup=$db->loadObjectList(); // End of addition } else { $row->pages = null; }
Přidali jsme větev else if, kdy testujeme jestli ID menu obsahuje hodnotu -1, kde určujeme hodnotu přepínače nad seznamem položek menu na exclude($row->pages) a načítáme položky menu, kde se modul nemá zobrazovat. Následně se přesuneme do druhého souboru do funkce edit(). Tady upravíme trošku roztáhnuté zobrazení přepínačů:
<?php if ($row->pages == 'all') { ?> <label for="menus-all"><input id="menus-all" type="radio" name="menus" value="all" onclick="allselections();" checked="checked" /><?php echo JText::_( 'All' ); ?></label> <label for="menus-none"><input id="menus-none" type="radio" name="menus" value="none" onclick="disableselections();" /><?php echo JText::_( 'None' ); ?></label> <label for="menus-select"><input id="menus-select" type="radio" name="menus" value="select" onclick="enableselections();" /><?php echo JText::_( 'Select From List' ); ?></label> <!-- Start of addition by Filip Bartmann, http://joomladev.eu --> <label for="menus_exclude"><input id="menus-exclude" type="radio" name="menus" value="exclude" onclick="enableselections();" /><?php echo JText::_('Select Excluded From List'); ?></label> <!-- End of addition --> <?php } elseif ($row->pages == 'none') { ?> <label for="menus-all"><input id="menus-all" type="radio" name="menus" value="all" onclick="allselections();" /><?php echo JText::_( 'All' ); ?></label> <label for="menus-none"><input id="menus-none" type="radio" name="menus" value="none" onclick="disableselections();" checked="checked" /><?php echo JText::_( 'None' ); ?></label> <label for="menus-select"><input id="menus-select" type="radio" name="menus" value="select" onclick="enableselections();" /><?php echo JText::_( 'Select From List' ); ?></label> <!-- Start of addition by Filip Bartmann, http://joomladev.eu --> <label for="menus_exclude"><input id="menus-exclude" type="radio" name="menus" value="exclude" onclick="enableselections();" /><?php echo JText::_('Select Excluded From List'); ?></label> <?php } else if($row->pages == 'exclude') { ?> <label for="menus-all"><input id="menus-all" type="radio" name="menus" value="all" onclick="allselections();" /><?php echo JText::_( 'All' ); ?></label> <label for="menus-none"><input id="menus-none" type="radio" name="menus" value="none" onclick="disableselections();" /><?php echo JText::_( 'None' ); ?></label> <label for="menus-select"><input id="menus-select" type="radio" name="menus" value="select" onclick="enableselections();" /><?php echo JText::_( 'Select From List' ); ?></label> <label for="menus_exclude"><input id="menus-exclude" type="radio" name="menus" value="exclude" onclick="enableselections();" checked="checked"/><?php echo JText::_('Select Excluded From List'); ?></label> <!-- End of addition --> <?php } else { ?> <label for="menus-all"><input id="menus-all" type="radio" name="menus" value="all" onclick="allselections();" /><?php echo JText::_( 'All' ); ?></label> <label for="menus-none"><input id="menus-none" type="radio" name="menus" value="none" onclick="disableselections();" /><?php echo JText::_( 'None' ); ?></label> <label for="menus-select"><input id="menus-select" type="radio" name="menus" value="select" onclick="enableselections();" checked="checked" /><?php echo JText::_( 'Select From List' ); ?></label> <!-- Start of addition by Filip Bartmann, http://joomladev.eu --> <label for="menus_exclude"><input id="menus-exclude" type="radio" name="menus" value="exclude" onclick="enableselections();" /><?php echo JText::_('Select Excluded From List'); ?></label> <!-- End of addition --> <?php } ?>
V podstatě do všech tři existujících větví if přidáme radiobutton menus-exclude a přidáme novou větev, se zaškrtnutým radiobuttonem. Drobnou úpravu provedeme také v tabulkovém zobrazení ve funkci view() kolem řádku 165:
if (is_null( $row->pages )) { echo JText::_( 'None' ); // Start of modification by Filip Bartmann, http://joomladev.eu } else if ($row->pages > 0 || $row->pages == -1) { //End of modification echo JText::_( 'Varies' ); } else { echo JText::_( 'All' ); }
Tady pouze přidáme k podmínce jestli je hodnota $row->pages >0 podmínku $row->pages == -1. Poté se opět přesuneme do souboru controller.php, kde musíme zajistit správné uložení, které se nachází ve funkci save(). Začneme přídáním následující kódu, který zajišťuje vymazání existujících přířazení vyloučených položek menu:
// Start of addition by Filip Bartmann, http://joomladev.eu $query = 'DELETE FROM #__modules_menu_exclude' . ' WHERE moduleid = '.(int) $row->id ; $db->setQuery( $query ); if (!$db->query()) { return JError::raiseWarning( 500, $db->getError() ); } // End of addition
Kód umístíme za předchozí SQL příkaz DELETE FROM #__modules_menu WHERE ... .Hlavní práci je ale přidání větve ifu:
else if($menus=="exclude") { $query = 'INSERT INTO #__modules_menu' . ' SET moduleid = '.(int) $row->id.' , menuid = -1' ; $db->setQuery( $query ); if (!$db->query()) { return JError::raiseWarning( 500, $db->getError() ); } foreach ($selections as $menuid) { // this check for the blank spaces in the select box that have been added for cosmetic reasons if ( (int) $menuid >= 0 ) { // assign new module to menu item associations $query = 'INSERT INTO #__modules_menu_exclude' . ' SET moduleid = '.(int) $row->id .', menuid = '.(int) $menuid ; $db->setQuery( $query ); if (!$db->query()) { return JError::raiseWarning( 500, $db->getError() ); } } } }
V této větvi uložíme do pole menuid hodnotu -1. Následně uložíme do naší tabulky #__modules_menu_exclude ID položek nabídky, kde se daný modul nemá zobrazovat. Tímto máme za sebou hlavní úpravy. Následující úpravy ve funkcích copy() a remove() je nutné provést, aby nám moduly fungovaly korektně. Ve funkci copy() zajišťující kopírování modulů si hned za načtení ID položek menu přidáme načtení vyloučených položek menu z naší nové tabulky:
// Start of addition by Filip Bartmann, http://joomladev.eu $query = 'SELECT menuid' . ' FROM #__modules_menu_exlude' . ' WHERE moduleid = '.(int) $cid[0] ; $db->setQuery( $query ); $rows = $db->loadResultArray(); foreach ($rows as $menuid) { $excluded[] = '('.(int) $row->id.','.(int) $menuid.')'; } // End of addition
Tyto ID následně uložíme s novým ID modulu:
// Start of addition by Filip Bartmann, http://joomladev.eu if (!empty( $excluded )) { // Module-Menu Mapping: Do it in one query $query = 'INSERT INTO #__modules_menu_exclude (moduleid,menuid) VALUES '.implode( ',', $excluded ); $db->setQuery( $query ); if (!$db->query()) { return JError::raiseWarning( 500, $db->getError() ); } } // End of addition
Ve funkci remove() je samozřejmě nutné stávající přiřazení zrušit, což provedeme kódem:
// Start of addition by Filip Bartmann, http://joomladev.eu $query = 'DELETE FROM #__modules_menu_exclude' . ' WHERE moduleid IN ( '.$cids.' )' ; $db->setQuery( $query ); if (!$db->query()) { return JError::raiseError( 500, $db->getErrorMsg() ); } // End of addition
Kód přidáme za vymazání přířazení z tabulky #__modules_menu.
Instalátor modulů
Stejnou úpravu provedeme podle očekávání také ve funkcích uninstall() a _rollback_menu() v instalátoru modulu v souboru /libraries/joomla/installer/adapters/module.php. Ve funkci uninstall() bude kód vymazání přířazení vypadat takto:
// Start of addition by Filip Bartmann, http://joomladev.eu $query = 'DELETE' . ' FROM #__modules_menu_exclude' . ' WHERE moduleid IN ('.$modID.')'; $db->setQuery($query); if (!$db->query()) { JError::raiseWarning(100, JText::_('Module').' '.JText::_('Uninstall').': '.$db->stderr(true)); $retval = false; } // End of addition
Do funkce _rollback_menu() umístíme tento kód:
// Start of addition by Filip Bartmann, http://joomladev.eu $query = 'DELETE' . ' FROM `#__modules_menu_exclude`' . ' WHERE moduleid='.(int)$arg['id']; $db->setQuery($query); if($db->query() { return false; } // End of addition
Tento kód vložíme nad vymazání přířazení z tabulky #__modules_menu.
Zobrazení modulů
Nejméně práce nám kupodivu dá zobrazení modulů, které má na starosti soubor /libraries/joomla/application/module/helper.php. Drobná úprava se týká pouze funkce _load(), kde upravíme pomocí vylučujícího poddotazu podmínku WHERE určující zobrazené moduly:
// Start of addition by Filip Bartmann, http://joomladev.eu $subquery="SELECT moduleid FROM #__modules_menu_exclude \n"; $subquery.="WHERE menuid=".(int)$Itemid; // End of addition // Start of modification by Filip Bartmann, http://joomladev.eu $wheremenu = isset( $Itemid ) ? ' AND ( mm.menuid = '. (int) $Itemid .' OR mm.menuid = 0 OR mm.menuid = -1) AND m.id NOT IN('.$subquery.')' : ''; // End of modification
Do proměnné $wheremenu jsme přidali pouze dvě úpravy a to část OR mm.menuid=-1 a následně vylučující podmínku poddotazu AND m.id NOT ID(poddotaz).
Závěr
Těmito úpravami jsme dostali i do stávající Joomly 1.5 docela užitečnou funkci připravované Joomly 1.6. Celý patch najdete také v sekci ke stažení.
Články


