DomůČlánkyTipy a trikyPřidáváme nastavení kde se moduly nemají zobrazovat

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í.

Komentářů (0)
Přidat komentář
YOUR_CONTACT_DETAILS:
Komentářů:
[b] [i] [u] [s] [url] [quote] [code] [img]   
:angry::0:confused::cheer:B):evil::silly::dry::lol::kiss::D:pinch:
:(:shock::X:side::):P:unsure::woohoo::huh::whistle:;):s
:!::?::idea::arrow:
SECURITY
Prosím=vložte text z obrázku (anti-SPAM ochrana

Zprávičky

Napsat novou zprávičku  |  Vše

sh404SEF 2.0.3.545

Nová verze

Napsal Peter Smrčák | 13.08 22:12

Kunena 1.6 RC1

Nová verze

Napsal Peter Smrčák |  9.08 15:28

Vyšla nová Kunena RC1 pre pripravovanú Joomlu 1.6.

EasyBook reloaded!

Nová verze

Napsal Peter Smrčák |  4.08 06:41

Vyšla stabilná verzia obľúbenej návštevnej knihy EasyBook reloaded vo verzii 2.0.4.

VirtueMart 1.1.5

Nová verze

Napsal Peter Smrčák | 28.07 15:11

Práve vyšiel nový VirtueMart.

Táto verzia opravuje rôzne problémy.

changelog | download

Joomla 1.5.19

Bezpečnost

Napsal Filip Bartmann | 16.07 18:30

Dnešním dnem spatřila světlo světa další aktualizace stabilní řady Joomly 1.5, tentokrát s pořadovým číslem 19 a kódovým jménem Wojmamni ama batani. Jedná se o opravu několika menších bezpečnostních chyb v administraci a také novou verzi js frameworku Mootools.

Více...

Jméno Joomla!® je použito pod limitovanou licenci od Open Source Matters ve Spojených státech a ostatních zemích. Joomladev nemá spojení s Open Source Matters, nebo projektem Joomla! a není součástí jejich podpory
Logo Joomla!® je použito pod limitovanou licenci od Open Source Matters ve Spojených státech a ostatních zemích. http://joomladev.eu nemá spojení s Open Source Matters, nebo projektem Joomla! a není součástí jejich podpory