ItemManager API Reference - Working with Items

Erstellt am: Monday 30 January 2017  |  Letzte Änderung am: Thursday 13 September 2018

This article offers a description of how to use items. It includes description of methods for getting, filtering, saving and deleting items. Each of these is documented below, following by several examples.

ItemMapper class

Use ItemMapper class if you want to interact with items. ItemManager offers two types of item objects that you can use for your purposes depending on the type of application. However, in most cases the use of SimpleItem objects is recommended and the use of standard Item objects should be limited to write access only.

Since ItemManager may have several categories, with hundreds or thousands of items, it would probably not be a good idea to automatically load all of these items into the memory. That's why you have to load the items from one or more categories manually into memory as needed. However, since all items can belong to different categories, you should specify the id of a category whose items you want to load. If you do not know the id of the category, you can also refer to it by name or another attribute. If you need more information on how to interact with categories, you should read this article first Working with categories. Throughout the description below, we will assume that the category id is already known.

Load SimpleItems of a specific category into memory

To load SimpleItem objects use ItemMapper's method alloc(category_id):

$imanager = imanager();
$itemMapper = $imanager->getItemMapper();
$itemMapper->alloc(5); // Loads SimpleItem objects of the category with id 5 into memory

Note that these three lines above in the example also applies to all examples below, it has been left out of later examples for brevity.

Now that we have the items in memory, we can interact with them, let's go a step further and see the getSimpleItem() method.

Select a single item

The ItemMapper's getSimpleItem(selector) method is best suited for selecting a specific item:

$item = $itemMapper->getSimpleItem('name=Banana');
if($item) {
    echo "Item $item->name was found.";
}

Of course you can also use another attribute or field to refer to the items. For example, if your category has a custom field price, you can select an item with a price of exactly 2.45:

$item = $itemMapper->getSimpleItem('price=2.45');

Select multiple items

The getSimpleItems(selector) method is best suited for find and return all items matching the given selector string. If you want to get all published items of a category, you can do this as follows:

$items = $itemMapper->getSimpleItems('active=1');

The foreach() loop is the best way to process the returned items further:

if($items) {
    foreach($items as $item) {
        echo "<p>Item: $item->name</p><br>\r\n";
    }
}

The getSimpleItems(selector) method becomes useful if you are going to do some more complex queries. So that, you could select all bananas with a price between 1.99 and 4.00 Euro, for example:

// gets all bananas
$items = $itemMapper->getSimpleItems('name=Banana');
if($items) {
	// gets bananas with a price between 1.99 and 4.00
	$items = $itemMapper->getSimpleItems('price>=1.99 && price<=4.00', null, null, $items);
}

The getSimpleItems(selector) method accepts the following selector operators:

=Equal to
!=Not equal to
<Less than
>Greater than
<=Less than or equal to
>=Greater than or equal to
search%Like pattern starting with
%searchLike pattern ending with
%search%Containing the pattern

How to limit the number of results returned from getSimpleItems()? This example shows how to get only the firs 10 items from a category:

$items = $itemMapper->getSimpleItems('name=Banana', 0, 10);

Shows 10 items with an offset of 10:

$items = $itemMapper->getSimpleItems('name=Banana', 10, 10);

Filtering items

You can use the filterSimpleItems() filter function to sort the items returned by the getSimpleItems() method:

ItemMapper::filterSimpleItems(
    string $filterby, string $option, int $offset, int $length, array $items
)

Returns an array of filtered items that match the given conditions. The method accepts the following parameter:

$filterby A sort by attribute: id, name, position, created, updated, or the custom field names (default position).
$option [optional] The order by key is used to sort the result-set in ascending or descending order: ASC or DESC (default ASC).
$offset [optional] Argument specifies the offset of the first record to return.
$length [optional] Specifies the last record number to return.
$items [optional] Preferable $items array for filtering. If empty, the method uses the already buffered items in $itemMapper->simpleItems variable.

Filter items by name in descending order:

$filteredItems = $itemMapper->filterSimpleItems('name', 'DESC', $items);

Get all bananas filtered by price and select two cheapest ones:


$items = $itemMapper->getSimpleItems('name=Banana');
$filteredItems = $itemMapper->filterSimpleItems('price', 'ASC', null, 2, $items);
        

Paginate

The ItemMapper class can be used to render navigation for pagination:

$pagination = $itemMapper->pagination($params, $tpls);

The method can optionally take two parameters:

$params [ optional ] An array with parameters (see below).
$tpls [ optional ] An array of templates to be used for rendering pagination (see below).
$params = array(
    'pageurl' => '?page=', // [ optional ] or 'page' if you prefer to use canonical url for pagination
    'page' => $_GET['page'],    // [ optional ] the current page number, ItemManager uses the page parameter by default
    'count' => count($items),  // [ optional ] the total number of items, ItemManager uses the the total number of items from last select by default
    'limit' => 10,  // [ optional ] items per page to show, the max. number in settings by default
    'lastpage' => count($items) / limit // [ optional ] last page number, automatically calculates by default
);
        
$tpls = array(
    'wrapper' => '<div class="paginator-wrapper">[[value]]</div>',
    'prev' => '<a class="paginator-left" href="[[href]]">PREV</a>',
    'prev_inactive' => '<span class="paginator-disabled">PREV</span>',
    'central' => '<a class="paginator-link" href="[[href]]">[[counter]]</a>',
    'central_inactive' => '<span class="paginator-current">[[counter]]</span>',
    'next' => '<a class="paginator-right" href="[[href]]">NEXT</a>',
    'next_inactive' => '<span class="paginator-disabled">NEXT</span>',
    'ellipsis' => '...',
    'secondlast' => '<a href="[[href]]">[[counter]]</a>',
    'second' => '<a href="[[href]]">[[counter]]</a>',
    'last' => '<a href="[[href]]">[[counter]]</a>',
    'first' => '<a href="[[href]]">1</a>'
);

If the $params and $tpls arrays were not passed, ItemManager uses the default values shown above.

Below a simple example script for pagination, which shows the list of all active items, split into several pages of 2 items per page:

// Change this as needed
$category_id = 5;
$perpage = 2;
// Initialize our instances
$imanager = imanager();
$itemMapper = $imanager->getItemMapper();
$itemMapper->alloc($category_id);
// Prepare splitting parameter for filter function 
$page = isset($_GET['page']) ? (int) $_GET['page'] : 1;
$next = ($page - 1) * $perpage + 1;
// Select active items
$active = $itemMapper->getSimpleItems('active=1');
$items = null;
if($active) {
    // We use filter function to split the items
    $items = $itemMapper->filterSimpleItems('position', 'ASC', $next, $perpage, $active);
}

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

    // Output item name and price
    echo "<h3>Items</h3>\r\n";
    foreach($items as $item) {
        echo "<p>Name: $item->name | Price: $item->price</p>\r\n";
    }
    // Output pagination
    echo $pagination;
}

Creating items

New items can be created very easily with ItemManager API. To create a new item, create a new instance of the Item object. The Item expects a category id as a parameter.

$newItem = new \Item($category_id);
$newItem->set('name', 'Strawberry');
$newItem->set('active', 1);
$newItem->setFieldValue('description', 'The garden strawberry is a widely grown hybrid species of the genus Fragaria, collectively known as the strawberries.');
$newItem->setFieldValue('price', 4.56);
$newItem->save();

ItemManager does not restrict you to set and access field values directly:

$newItem->fields->description->value = 'Your text coming here ...';

Just a reminder about security: Please always be aware about sanitizing the user input with regard to the context. The ItemManager's Sanitizer class provides functions to fill the most common data sanitization needs with items, categories and fields created in ItemManager. However, in many cases the htmlspecialchars() function is sufficient to prepare input for inclusion in most contexts of an HTML document.

$newItem->fields->description->value = $imanager->sanitizer->textarea('Your text coming here ...');
// another methods 
$imanager->sanitizer->text('Text field values');
$imanager->sanitize->name('Item and category names');
$imanager->sanitize->pageName('Value for slug fields');
$imanager->sanitize->email('Value for email');
        ...

The setFieldValue() method automatically checks the content depending on the field type:

$item->setFieldValue('description', $_POST['user_input']));

Note that the content is checked differently depending on the field type, if you want to save the Markup/HTML as content, you should use WYSIWYG editor as a field type, or sanitize the fields manually. The PHP function htmlspecialchars() can help you do this, the function htmlspecialchars_decode() at output could then decode the content again. You can disable the sanitizing of the content with a third parameter:

// Disable the field sanitizing
$item->setFieldValue('description', htmlspecialchars($content), false);
// At the output
echo htmlspecialchars_decode($item->description);

The htmlspecialchars_decode($item->description); can be dangerous if you are not 100% sure about the origin of the content.

Item::setFieldValue() method returns true if the field value has been correctly set, otherwise false.
You can also access the Validation Error number with MsgReporter::errorCode()
The following table describes error codes on setting field values:

Code Description
1 Required field empty
2 The length of field value is less than *minimum*
3 The length of field value is greater than *maximum*
4 Currently not used
5 Incomplete field values
6 Undefined error
7 Unequal field values
8 Invalid value format for this fieldtype

Example outputs error code:

$newItem = new Item($category_id);
// name is an attribute and not a custom field, use "Item::set()" + "Sanitizer::name()"
$newItem->set('name', $imanager->sanitizer->name('Honey'));
// description is a custom field, use setFieldValue() for validation
if(true !== $newItem->setFieldValue('description',
        '<p><strong>Honey</strong> is a sweet, viscous food substance 
            produced by bees and some related insects.</p>')
) {
    echo "<h3>An error occurred while setting a field value:<h3>\r\n";
    echo 'Error code: '.MsgReporter::errorCode();
} else {
    echo "<h3>No errors, item can be saved<h3>\r\n";
    // $newItem->save();
}

Item Update

The item update is exactly the same, but you must select your item first. Note that we have to use a getItem() method to select instead of getSimpleItem(), because it's not a SimpleItem object (write accesses are handled with default Item object). We also don't use alloc() here, but the init($category_id) method:

$category_id = 5;

$itemMapper->init($category_id);
$myItem = $itemMapper->getItem('name=Honey');

if($myItem && $myItem->setFieldValue('price', 6.99)) {
    if($myItem->save()) echo 'Item was saved';
}

Backup items

This will create a backup of an item:

$category_id = 5;

$itemMapper->alloc($category_id);
$item = $itemMapper->getSimpleItem('name=Honey');

// Build id selector
$ids = "$item->id.$item->categoryid";
if($imanager->config->createBackup(IM_ITEM_DIR, $ids, IM_ITEM_FILE_SUFFIX)) {
    echo 'Your backup was created successfully!';
}

You can find the item backups under: /backups/other/imanager/backup_*_*.*.im.item.xml folder

Delete item

IManager::deleteItem() - deletes the entire item data, all the contents like images, files, etc will be removed recursively:

$imanager->deleteItem($item_id, $category_id);

Autor: Bigin  |  Tags:  FrameworkGetSimplePHPDevelopmentItemManager