The use of SimpleItem objects

Erstellt am: Thursday 16 February 2017  |  Letzte Änderung am: Saturday 11 August 2018

From version 2.3.8 ItemManager provides new object type named SimpleItem. As their name suggests, these objects are lightweight and very easy to use.

In the example below I will show you how to build a large product lists with pagination, for 2000 and more items.

In contrast to regular Item objects, SimpleItem objects that belong to the same category are always loaded all at once, this can have advantages as well as disadvantages. The SimpleItem objects are loaded into memory much faster than the regular items, but you cannot select specific objects to load separately.

Another advantage of SimpleItem objects is the ability to access custom fields more easily. For example, if you wanted to access the contents of a field of a regular Item object, you had to address the contents through several nested objects:

echo $item->fields->field_name->value;

In contrast to this, you can access the content of a SimpleItem object field directly:

echo $item->field_name;

As the SimpleItem objects are stored differently, a slightly additional hard disk space is required for its use. You can prevent the use of SimpleItem objects by setting the $useAllocater variable in /plugins/imanager/lib/inc/config.php file to false. However, this is not recommended because many plugins based on ItemManager access SimpleObject, which will cause issues.

The basics:

Call the ItemMapper's method alloc() to instruct ItemManager to load the SimpleItem objects of a certain category into memory:

$itemMapper->alloc($catid);

... where $catid is the id of the category whose objects you want to load.

After calling the method, all loaded objects are in the memory, which you can now access via the member variable $simpleItems:

foreach($itemMapper->simpleItems as $item) {
    \Util::preformat($item);
}

In most cases, however, you will only want to access certain items. For example, to get only active items you can use the getSimpleItems() method:

$activeItems = $itemMapper->getSimpleItems('active=1');
foreach($activeItems as $item) {
    \Util::preformat($item);
}

Another very useful method is the filterSimpleItems(). In addition to various useful filter and sort functions, it also allows a limited selection of items. This method can be applied to the entire $simpleItems array as well as to the selected items. Far instance, application to the entire array:

$itemMapper->alloc($catid);
$simpleItems = $itemMapper->filterSimpleItems('position', 'DESC', $offset, $perpage);

Application to the pre-selected items:

$itemMapper->alloc($catid);
$activeItems = $itemMapper->getSimpleItems('active=1');
$simpleItems = $itemMapper->filterSimpleItems('position', 'DESC', $offset, $perpage, $activeItems);

This method can be very helpful when building a page limited output of items (pagination). For example, to display only 2 items per page you can proceed like this:

$itemMapper->alloc($catid);
$activeItems = $itemMapper->getSimpleItems('active=1');

// Prepare offset parameter for the filter function
$perpage = 2;
$page = isset($_GET['page']) ? (int) $_GET['page'] : 1;
$offset = ($page - 1) * $perpage + 1;

$simpleItems = $itemMapper->filterSimpleItems('position', 'DESC', $offset, $perpage, $activeItems);

foreach($simpleItems as $item) {
	\Util::preformat($item);
}

Note also that a page parameter is expected here so that the splitting of the output works. Okay, only the markup for the navigation is still missing here, you create it fully automatically with the pagination() method:

$itemMapper->alloc($catid);
$activeItems = $itemMapper->getSImpleItems('active=1');

// Prepare offset parameter for the filter function
$perpage = 2;
$page = isset($_GET['page']) ? (int) $_GET['page'] : 1;
$offset = ($page - 1) * $perpage + 1;

$simpleItems = $itemMapper->filterSimpleItems('position', 'DESC', $offset, $perpage, $activeItems);

if($simpleItems) {
	// Prepare pagination params
	$params = array('limit' => $perpage, 'count' => count($activeItems));
	// Create pagination markup
	$pagination = $itemMapper->pagination($params);

	// Outputs item name
	echo "<h3>Items</h3>\r\n";
	foreach($simpleItems as $item) {
		echo "<p>Name: $item->name</p>\r\n";
	}
	// Outputs navigation
	echo $pagination;
}

Here you can learn more about the pagination method.

To save an item as a SimpleItem object use simplify() and save() methods:

// load SimpleItem objects into the memory 
$itemMapper->alloc($catid);
// create a SimpleItem object from an item
$itemMapper->simplify($item);
// save SimpleItem object
$itemMapper->save();

Watch the video below to learn more about using SimpleItem objects

Creating large item lists with pagination

As already mentioned, the ItemMapper::pagination() method is designed to automatically paginate the results of any API method that returns more than one item. In the next example, I will retrieve all items with active status 1, limit the results to 10, and sort them by position in descending order. The result would be all items of the category id 9 except not activated, retrieving a max of 10 at a time. This is a somewhat simple example, so you would most likely want to replace the selector in this example with your own selector. Regardless, you'll always want to specify a start and limit equal to the number of the start item and of results you want to show per page, when using pagination.

<?php
$catid = 9;
$imanager = imanager();
$itemMapper = $imanager->getItemMapper();
$limit = 10;
$start = !empty($_GET['page']) ? (((int)$_GET['page'] -1) * $limit +1) : 1;
$itemMapper->alloc($catid);
$simpleItems = $itemMapper->getSimpleItems('active=1');
$total = $itemMapper->countItems($simpleItems);
$simpleItems = $itemMapper->filterSimpleItems('position', 'DESC', $start, $limit, $simpleItems);
$pagination = $itemMapper->pagination('limit' => $limit, 'count' => count($simpleItems));
?>
<div class="row">
    <table class="u-full-width">
        <thead>
            <tr>
                <th>Name</th>
                <th>Created</th>
                <th>Last update</th>
                <th>File name</th>
            </tr>
        </thead>
        <tbody>
        <?php
        foreach($simpleItems as $item) {
        ?>
            <tr>
                <td><?php echo $item->name; ?></td>
                <td><?php echo date('Y-m-d', $item->created); ?></td>
                <td><?php echo (!empty($item->updated) ? date('Y-m-d', $item->updated) : ''); ?></td>
                <td><?php echo $item->filename; ?></td>
            </tr>
        <?php
        }
        ?>
        </tbody>
    </table>
    <div><?php echo $pagination; ?></div>
    <div class="info-block">
        <p>Total: <?php echo $total; ?> items</p>
    </div>
</div>

You can see a demonstration of the pagination here: Demo Item List

Autor: Bigin  |  Tags:  FrameworkPHPGetSimpleDevelopmentItemManager