ItemManager API Reference - Working with categories

Erstellt am: Dienstag 27 Dezember 2016  |  Letzte Änderung am: Samstag 11 August 2018

This article offers a brief description of how you can create, edit and delete categories programmatically.

CategoryMapper class

You should always use the CategoryMapper class (category accessor) to access the ItemManager's categories.

$categoryMapper = $imanager->getCategoryMapper();

Get a single category by id or another attribute.

The following code shows how to get a category with a certain id:

$category = $categoryMapper->getCategory('id=1');

... or the short form:

$category = $categoryMapper->getCategory(1);

Note the short notation of the selector only works for id's

The approach is the same if you want to select a category by a certain attribute like id, name, slug, position, created or updated:

$category = $categoryMapper->getCategory('name=Your category name');
$category = $categoryMapper->getCategory('slug=your-category-slug');
$category = $categoryMapper->getCategory('position=3');
...

Select multiple categories

If you need to select more than one category, for example to get all the categories created after a certain date, you can use the categoryMapper's method getCategories(). To get all the categories that created date is on or later than 2017-07-06 15:03:21, you can do it this way:

$date = new \DateTime('2017-07-06 15:03:21');
$categories = $categoryMapper->getCategories('created>='.$date->getTimestamp());

getCategories() is a powerful method that allows you to specify various parameters to get the most accurate results:

Returns an array of categories that match the given selector considering other parameters. The method accepts the following parameter:

$stat The Selector string ('name=my name'), accepted operators (>=, <=, !=, >, <, =).
$offset [optional] Argument specifies the offset of the first record to return.
$length [optional] Specifies the last record number to return.
$categories [optional] Preferable $categories array to working with.

For example, if you want to limit the results to a number of 10 categories that first occur, you can do this as follows:

$date = new \DateTime('2017-07-06 15:03:21');
$categories = $categoryMapper->getCategories('created>='.$date->getTimestamp(), 0, 10);

You can also exclude the first 10 categories from the result:

$date = new \DateTime('2017-07-06 15:03:21');
$categories = $categoryMapper->getCategories('created>='.$date->getTimestamp(), 11, 10);

For complex queries, you can run the results through the function several times. So if you want to get the categories that created date is on or later than 2017-07-06 15:03:21 and have not yet been updated, you can run the results twice through the method:

// Gets all the categories not yet updated
$categories = $categoryMapper->getCategories('updated=0');
if($categories) {
    $date = new \DateTime('2017-07-06 15:03:21');
    // Note that $categories array is passed to the method as a parameter
    $categories = $categoryMapper->getCategories(
        'created>='.$date->getTimestamp(), null, null, $categories
     );
}

Category filter

The filterCategories() method allows filtering and sorting the results obtained from the getCategories method:

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

$filterby A sort by attribute: id, name, slug, position, created, updated.
$key [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.
$categories [optional] Preferable $categories array for filtering. If empty, the method uses the already buffered categories in $categoryMapper->categories variable.

Here is the way to do it if you want to sort your results by a certain attribute:

$date = new \DateTime('2017-07-06 15:03:21');
$categories = $categoryMapper->getCategories('created>='.$date->getTimestamp(), null, null, $categories);
$sortedCategories = $categoryMapper->filterCategories('name', 'DESC', null, null, $categories);
...

Create a new category

Creating a new category is really simple:

$newCategory = new \Category();
$newCategory->set('name', 'My Category');
$newCategory->set('slug', $newCategory->name);
if($newCategory->save()) {
	echo "A new category $newCategory->name was successfully created.";
}

Be careful when creating categories: To give the category a unique name and slug, you have to check if the category with the same name already exists.

To avoid duplicates you can try to select a category with the requested name, if it exists you can cancel the saving and show a message:

$newCategory = new \Category();
$newCategory->set('name', 'My Category');
$newCategory->set('slug', $newCategory->name);
// Check if a category with the same slug already exists
$exists = $imanager->getCategory('slug='.$newCategory->slug);
if(!$exists) {
	if($newCategory->save()) {
		echo "A new category $newCategory->name was successfully created.";
	}
} else {
	echo "Error: A Category with slug $newCategory->slug already exists!";
}

Update an existing category

In the same way you can do an update:

$category = $imanager->getCategory('name=My Category');
$category->set('name', 'My Category Updated');
$category->save();

Assign custom fields to a category

It's not very difficult to assign any custom fields to a category programmatically. The following script might seem complicated for some, but if you understand the logic, you can see that it is relatively simple. Let's assign 2 custom fields to our category called My Category Updated, the first one url and the second one description:

// Gets the category by name
$category = $imanager->getCategory('name=My Category Updated');

// Define the category fields
$fields = array(
	'cat' => $category->id, // The id of the category to which the fields should belong

	// Field 1
	'cf_0_key'   => 'url', // Field name. No special characters, no hyphens only underscores are allowed
	'cf_0_label' => 'Website', // Field label
	'cf_0_type'  => 'text', // Field type
	'cf_0_options' => '', // Useful for dropdown fields
	'cf_0_value' => '', // Field value

	// Field 2
	'cf_1_key'   => 'description',
	'cf_1_label' => 'Description',
	'cf_1_type'  => 'editor',
	'cf_1_options' => '',
	'cf_1_value' => ''
);
// Create fields and assign to the category
if($imanager->createFields($fields) !== true) {
	echo "Error when creating new fields for the category $category->name";
} else {
	// Set the default field parameters
	$fieldsdata = array(
		// Field 1 parameters
		array(
			'field' => 1, // Field id. Counting always starts at 1 here!
			'default' => '', // Default field value
			'info' => '', // Field info
			'required' => 0, // Is field required?
			'min_field_input' => 0, // Minimum field value length in characters
			'max_field_input' => 0, // Maximum field value length in characters
			'areaclass' => '', // Area CSS class (IM admin view)
			'labelclass' => '',// Label CSS class (IM admin view)
			'fieldclass' => '' // Field CSS class (IM admin view)
		),
		// Field 2 parameters
		array(
			'field' => 2,
			'default' => '',
			'info' => '',
			'required' => 0,
			'min_field_input' => 0,
			'max_field_input' => 0,
			'areaclass' => '',
			'labelclass' => '',
			'fieldclass' => ''
		)
	);

	// Set field data
	if(set_fieds_data($category->id, $fieldsdata) !== true) {
		echo "Error when saving field data for the category $category->name";
	} else {
		echo "Fields for the category $category->name were successfully created.";
	}
}

function set_fieds_data($category_id, $fieldsdata) {
	// Init FieldMapper class
	$fm = new \FieldMapper();
	$fm->init($category_id);

	// Loop through fielddata and assign it to the fields
	foreach($fieldsdata as $input)
	{
		// Field already exists
		$currfield = $fm->getField((int)$input['field']);

		if(!$currfield) {
			echo "Field id {$input['field']} was not found!<br>\r\n";
			continue;
		}

		$currfield->default = str_replace('"', "'", $input['default']);
		$currfield->info = str_replace('"', "'", $input['info']);
		$currfield->required = ($input['required']) ? 1 : null;
		$currfield->minimum = ((int) $input['min_field_input'] > 0) ? (int) $input['min_field_input'] : null;
		$currfield->maximum = ((int) $input['max_field_input'] > 0) ? (int) $input['max_field_input'] : null;
		$currfield->areaclass = str_replace('"', "'", $input['areaclass']);
		$currfield->labelclass = str_replace('"', "'", $input['labelclass']);
		$currfield->fieldclass = str_replace('"', "'", $input['fieldclass']);

		// Process custom Fieldtype settings
		foreach($input as $key => $value) {
			if(strpos($key, 'custom-') !== false) {
				$fieldkey = str_replace('custom-', '', $key);
				$currfield->configs->{$fieldkey} = $value;
			}
		}
		if(!$currfield->save()) { return false; }
	}

	return true;
}

Delete categories

There are two methods available to delete an existing category. ItemManager provides a secure deletion method deleteCategory(). This method expects two parameter: the first one, is the id of the category to be deleted and the second one is a refresh-flag, can be (optionally) passed to the method to initiate buffer refresh.

Note: If you use the secure deleteCategory() method, all existing items and fields belonging to this category will be also deleted automatically. The backup will be stored on the server, depending on your ItemManager settings.

$category = $imanager->getCategory('name=My Category Updated');
$imanager->deleteCategory($category->id);

Another way to delete categories is to use an insecure destroyCategory() method. The Category object is expected as a parameter.

Please note that if you use this method, the affected category will not be completely deleted and the meta data (fields and items as well as item data like images and files) will not be deleted, that may lead to problems elsewhere later. In order to avoid this, you will have to delete them manually.

$category = $imanager->getCategory('name=My Category Updated');
$categoryMapper->destroyCategory($category);

You can also always make a backup of your category file:

$imanager->config->createBackup(IM_CATEGORY_DIR, $category->id, IM_CATEGORY_FILE_SUFFIX);

Autor: Bigin  |  Tags:  GetSimpleFrameworkPHPScriptsDevelopmentItemManager