Hoe komt een nieuw feature in Joomla?

“De Categorie Item Teller”

door Peter Martin / @pe7er

Category Item Counter

Overzicht presentatie

  • Oorsprong Categorie Item Teller
  • Goedbewaarde geheim
  • Joomla's ontwikkeltraject
  • Mijn werkwijze
  • Generieker?
  • Problemen
  • Componenten leren tellen
  • Meer problemen

Oorsprong van "nice" feature

Joomladay Nice

Zaterdag 9 mei 2015, rond 15:00 uur

“It's a pity that the
Joomla Category Manager doesn't have
an Article Counter anymore”

Marc Dechèvre

Les 1

Deel je ideeën voor verbeteringen op een constructieve manier,
bij voorkeur in
persoonlijke gesprekken

(en niet op Twitter)

Joomla 1.5 - Category Manager

“That should not be
that hard to build in, should it?”

ondergetekende

(moest nog naar de kapper)

Les 2

Heb plezier

(of maak het)

deux bières

encore deux bières

Terug in het hotel

com_category,
een goedbewaarde geheim

Joomla 1.5 & categorieën

  • Artikelen (com_content):
    Artikelen + Artikelcategorieën

  • Banners, Contacts, Newsfeeds & Weblinks
    -> allemaal hun eigen categorieën

Categorie Item Counter: dmv SQL query worden items geteld

Joomla 3.x & categorieën

  • Categorieën (com_categories):
    generiek component

  • Artikelen, Banners, Contacts,
    Newsfeeds & Weblinks

    -> Eigen items + categorieën in com_categories

Artikelen & categorieën

  • Article Manager: Articles
    (Content > Article Manager)
    URL: /administrator/index.php
    ?option=com_content&view=articles

  • Category Manager: Articles
    (Content > Category Manager)
    URL: /administrator/index.php
    ?option=com_categories
    &extension=com_content

Banners & categorieën

  • Banner Manager: Banners
    (Components > Banners > Banners)
    URL: /administrator/index.php
    ?option=com_banners

  • Category Manager: Banners
    (Components > Banners > Categories)
    URL: /administrator/index.php
    ?option=com_categories
    &extension=com_banners

Gebruik com_categories in eigen component

in administrator/components/
com_yourcomponent/models/forms/some_item.xml

<field
	name="catid"
	type="category"
	extension="com_yourcomponent"
	default=""
	class="inputbox"
	label="JCATEGORY"
	description="JFIELD_CATEGORY_DESC"
	required="true">
		<option value="0">JOPTION_SELECT_CATEGORY</option>
</field>

Les 3

Beperk de omvang
van jouw project...

neem kleine stapjes

Mijn afbakening

com_categories

<?php
	if($extension == "com_content"):
	//voeg SQL optel query toe aan $query object
?>

Joomla's ontwikkeltraject

git

Software Versie beheer

  • Distributed - geen centrale server
  • Historisch overzicht code veranderingen

github.com

Software as a Service

github.com

  • PR = Pull Request
    vraag Joomla om code van jouw prive fork
    in Joomla code te trekken

  • RTC = Ready To Commit
    Drie succesvolle tests nodig
    → code misschien in volgende Joomla versie...

Les 4

Wees bereid om te testen

Patch Tester Component

  1. Installeer Joomla staging
    + standaard voorbeeld data
  2. Installeer Patch Testing Component
  3. Laad lijst met Pull Requests
  4. Lees test instructie, test
  5. installeer patch
  6. test, schrijf rapport
  7. uninstalleer patch

Joomla releases

Huidige versie: Joomla 3.5.1

Patch voor fout → volgende subversie (3.5.2)

Nieuwe Feature → volgende hoofdversie (3.6)
(labels: “milestone” + “New feature”)

Nieuwe taalstrings
(label: “new language string”)

Mijn werkwijze

Maak kopie (fork)

Clone naar PC

Deel nieuwe code

Les 5

Schrijf duidelijke
test instructies

Wordt getest

Schrijf duidelijke instructies

Automatische test

Codestyle test

2x handmatige test

Via https://issues.joomla.org/ testrapport

Les 6

Gebruik schermkopieën!
1 foto = 1.000 woorden

Voor PR

Na PR

“Hathor template?”
“Alignment looks bad”
“Travis is not happy... can you try to fix the Travis errors?”

Bijna...

Foto: Pierre Sempé

...maar nog niet helemaal

zo dan?

Satisfait & tevreden

Hathor... iemand?

Generieker = mooier

Les 7

Durf te vragen

Artikelen (com_content)

  • Artikel Manager: Artikelen
    via Content > Article Manager
    URL /administrator/index.php ?option=com_content
    &view=articles

  • Categorie Manager: Artikelen
    via Content > Category Manager
    URL /administrator/index.php?option=com_categories
    &extension=com_content

Linker menu in Artikelen

  • Category Manager (com_categories)
    weet via extension=com_content

    en vraagt om bestand
    /administrator/components/
    com_content/ helpers/content.php

    die genereert linker menu.

Uitbreiden $query

  • Category Manager (com_categories)
    administrator/components/
    com_categories/models/categories.php
    bevat protected function getListQuery()

    → $query object uitbreiden via
    $classname::countItems($query);

    → laad specifieke code van helper file
    van het extension=com_componentnaam component.

HTML output: kolomkop

  • administrator/components/com_categories/views/
    categories/tmpl/default.php
    <?php if (isset($this->items[0])
    && property_exists($this->items[0],
    'count_published')) :
    $columns++; ?>
    
    <th width="1%" class="nowrap center hidden-phone">
    <i class="icon-publish"></i>
    </th>
    
    <?php endif;?>

HTML output: klikbare teller

  • administrator/components/com_categories/views/
    categories/tmpl/default.php
    <?php if (isset($this->items[0])
    && property_exists($this->items[0], 'count_published')) : ?>
    
    <td class="center btns hidden-phone">
      <a class="badge <?php if ($item->count_published > 0)
      echo "badge-success"; ?>"
      title="<?php echo Jtext::_('COM_ CATEGORY_COUNT_PUBLISHED_ITEMS');?>"
      href="<?php echo JRoute::_('index.php?option=' . $component .
      '&filter[category_id]=' . (int) $item->id .
      '&filter[published]=1' .
      '&filter[level]=' . (int) $item->level);?>">
    
        <?php echo $item->count_published; ?>
    
    </a></td>
    <?php endif;?>

Meer problemen
in de core code

Aanroep van Filters

  • Status in core componenten
    &filter[published]


  • Status in Banners (com_banners)
    &filter[state]

Uitbreiden naar eigen component

Tel gepubliceerde items

/administrator/components/com_your_
component
/helpers/your_component.php

class YourcomponentHelper extends JHelperContent
{
  public static function countItems(&$query)
  {
    // Join articles to cats and count published items
    $query->select('COUNT(DISTINCT cp.id) AS count_published');
    $query->join('LEFT', '#__yourcomponent_items AS cp
    ON cp.catid = a.id AND cp.state = 1');

    return $query;
  }
}

Andere tellingen

// Count unpublished items
$query->select('COUNT(DISTINCT cu.id) AS count_unpublished');
$query->join('LEFT', '#__yourcomponent_items AS cu
ON cu.catid = a.id AND cu.state = 0');

// Count archived items
$query->select('COUNT(DISTINCT ca.id) AS count_archived');
$query->join('LEFT', '#__yourcomponent_items AS ca
ON ca.catid = a.id AND ca.state = 2');

// Count trashed items
$query->select('COUNT(DISTINCT ct.id) AS count_trashed');
$query->join('LEFT', '#__yourcomponent_items AS ct
ON ct.catid = a.id AND ct.state = -2');

Joomla, we have a problem

Net voor uitkomen Joomla 3.5.0

Tellen maar...

Sommige sites :-)

Performance probleem

“Categorie Manager is traag op site met 85,000 artikelen in 100 categorieeën” https://github.com/joomla/joomla-cms/pull/6916#issuecomment-195671451

SQL: COUNT(DISTINCT)

“New category count feature performance degrade #9420”
“Database queries total: 46.3 ms > 31,358.46 ms (31 sec!)”
https://github.com/joomla/joomla-cms/pull/9420

Anders tellen...

https://github.com/joomla/joomla-cms/pull/9421

1. Verplaatst

administrator/components/
com_categories/models/categories.php

// Load Helper file of the component for
// which com_categories displays the categories
$classname = ucfirst(substr($extension, 4)) . 'Helper';

if (class_exists($classname) && method_exists($classname,
'countItems'))
{
  // Get the SQL to extend the com_category $query object
  // with item count (published, unpublished, trashed)
  // $classname::countItems($query);
  $classname::countItems($this->items);
}
naar administrator/components/
com_categories/views/categories/tmpl/default.php

2. Verwijderd

administrator/components/
com_content/helpers/content.php

Opbouw $query object verwijderd:

$query->select('COUNT(DISTINCT cp.id) AS count_published');
$query->join('LEFT', '#__content AS cp
ON cp.catid = a.id AND cp.state = 1');

3a. Veranderd

administrator/components/
com_content/helpers/content.php

public static function countItems(&$items)
{
  $db = JFactory::getDbo();
  foreach ($items as $i => $item)
  {
    $item->count_trashed = 0;
    $item->count_archived = 0;
    $item->count_unpublished = 0;
    $item->count_published = 0;
    $query = $db->getQuery(true);
    $query->select('state, count(*) AS count')
          ->from($db->qn('#__content'))
          ->where('catid = ' . (int) $item->id)
          ->group('state');
    $db->setQuery($query);

3b. Veranderd

administrator/components/
com_content/helpers/content.php

    $arts = $db->loadObjectList();

    foreach ($arts as $i => $art) {
      if ($art->state == 1) { $item->count_published = $art->count; }

      if ($art->state == 0) {
          $item->count_unpublished = $art->count; }

      if ($art->state == 2) { $item->count_archived = $art->count; }

      if ($art->state == -2) { $item->count_trashed = $art->count; }
    }
  }
return $items;
}

Prob 2: New countItems feature

“only works for basic category calls without sections
because the extension string is not handled properly”

https://github.com/joomla/joomla-cms/pull/9580 (fixed #9186 #9462 )

Samenvatting

Samenvatting

  1. Deel je ideeën voor verbeteringen
    op een constructieve manier,
    bij voorkeur in persoonlijke gesprekken
    (en niet op Twitter)
  2. Heb plezier (of maak het)
  3. Beperk de omvang van jouw project... neem kleine stapjes
  4. Wees bereid om te testen
  5. Schrijf duidelijke test instructies
  6. Gebruik schermkopieën! 1 foto = 1.000 woorden
  7. Durf te vragen

Bedankt

Thanks to everybody that helped developing this new feature!

Peter Martin
e-mail: info at db8.nl
twitter: @pe7er
presentation: https://db8.nl

Credits