Permalink
Browse files

feature(icons): adds a service for handling entity icons

Adds a number of methods to handle entity icons in a unified manner.
Adds PHPUnit tests.

Refs #6152
  • Loading branch information...
brettp authored and mrclay committed Apr 14, 2015
1 parent c908c76 commit 72b8a2c78d997277f24e57db834f96f6fd779e92
View
@@ -168,17 +168,49 @@ EntityType/default.
Entity Icons
~~~~~~~~~~~~
Every entity can be assigned an icon which is retrieved using the ``ElggEntity::getIconURL($params)`` method.
This method accepts a ``$params`` argument that can be either a string specifying on of the configured icon sizes,
or an array of parameters, that specify the size and provide additional context for the hook to determine the icon
to serve.
Entity icons can be saved from uploaded files, existing local files, or existing ElggFile
objects. These methods save all sizes of icons defined in the system.
Use ``elgg_get_config('icon_sizes')`` to get all possible values. The following sizes exist by default:
``'large'``, ``'medium'``, ``'small'``, ``'tiny'``, and ``'topbar'``. The method triggers the
``entity:icon:url`` :ref:`hook <guides/hooks-list#other>`.
.. code:: php
$object = new ElggObject();
$object->title = 'Example entity';
$object->description = 'An example object with an icon.';
// from an uploaded file
$object->setIconFromUploadedFile('file_upload_input');
// from a local file
$object->setIconFromLocalFile('/var/data/generic_icon.png');
// from a saved ElggFile object
$file = get_entity(123);
if ($file instanceof ElggFile) {
$object->setIconFromElggFile($file);
}
$object->save();
The following sizes exist by default:
* ``master`` - 550px at longer edge (not upscaled)
* ``large`` - 200px at longer edge (not upscaled)
* ``medium`` - 100px square
* ``small`` - 40px square
* ``tiny`` - 25px square
* ``topbar`` - 16px square
Use ``elgg_get_icon_sizes()`` to get all possible icon sizes for a specific entity type and subtype.
The function triggers the ``entity:icon:sizes`` :ref:`hook <guides/hooks-list#other>`.
To check if an icon is set, use ``$object->hasIcon($size)``.
You can retrieve the URL of the generated icon with``ElggEntity::getIconURL($params)`` method.
This method accepts a ``$params`` argument as an array that specifies the size, type, and provide
additional context for the hook to determine the icon to serve.
The method triggers the ``entity:icon:url`` :ref:`hook <guides/hooks-list#other>`.
Use ``elgg_view_entity_icon($entity, $size, $vars)`` to render an icon. This will scan the following
locations for a view and include the first match.
locations for a view and include the first match to .
#. views/$viewtype/icon/$type/$subtype.php
#. views/$viewtype/icon/$type/default.php
@@ -193,9 +225,23 @@ $type
$subtype
Entity subtype, e.g. ``'blog'`` or ``'page'``.
By convention entities that have an uploaded avatar or icon will have the ``icontime`` property
assigned. This means that you can use ``$entity->icontime`` to check if an icon exists for the given
entity.
Icon methods support passing an icon type if an entity has more than one icon. For example, a user
might have an avatar and a cover photo icon. You would pass ``'cover_photo'`` as the icon type:
.. code:: php
$object->setIconFromUploadedFile('uploaded_photo', 'cover_photo');
$object->getIconUrl([
'size' => 'medium',
'type' => 'cover_photo'
]);
Note that custom icon types (e.g. cover photos) do not have preset sizes and coordinates.
Use ``entity:<icon_type>:url`` :ref:`hook <guides/hooks-list#other>` to configure them.
By default icons will be stored in ``/icons/<icon_type>/<size>.jpg`` relative to entity's directory on filestore.
To provide an alternative location, use the ``entity:<icon_type>:file`` :ref:`hook <guides/hooks-list#other>`.
Adding, reading and deleting annotations
----------------------------------------
View
@@ -367,6 +367,13 @@ Other
"container_guid" (int) are provided. An empty entity value generally means the form is to
create a new object.
**entity:icon:sizes, <entity_type>**
Triggered by ``elgg_get_icon_sizes()`` and sets entity type/subtype specific icon sizes.
``entity_subtype`` will be passed with the ``$params`` array to the callback.
**entity:<icon_type>:sizes, <entity_type>**
Allows filtering sizes for custom icon types, see ``entity:icon:sizes, <entity_type>``
**entity:icon:url, <entity_type>**
Triggered when entity icon URL is requested, see :ref:`entity icons <guides/database#entity-icons>`. Callback should
return URL for the icon of size ``$params['size']`` for the entity ``$params['entity']``.
@@ -413,6 +420,54 @@ Other
return "http://www.gravatar.com/avatar/$hash?s=$size";
}
**entity:<icon_type>:url, <entity_type>**
Allows filtering URLs for custom icon types, see ``entity:icon:url, <entity_type>``
**entity:icon:file, <entity_type>**
Triggered by ``ElggEntity::getIcon()`` and allows plugins to provide an alternative ``ElggIcon`` object
that points to a custom location of the icon on filestore. The handler must return an instance of ``ElggIcon``
or an exception will be thrown.
**entity:<icon_type>:file, <entity_type>**
Allows filtering icon file object for custom icon types, see ``entity:icon:file, <entity_type>``
**entity:<icon_type>:prepare, <entity_type>**
Triggered by ``ElggEntity::saveIcon*()`` methods and can be used to prepare an image from uploaded/linked file.
This hook can be used to e.g. rotate the image before it is resized/cropped, or it can be used to extract an image frame
if the uploaded file is a video. The handler must return an instance of ``ElggFile`` with a `simpletype`
that resolves to `image`. The ``$return`` value passed to the hook is an instance of ``ElggFile`` that points
to a temporary copy of the uploaded/linked file.
The ``$params`` array contains:
* ``entity`` - entity that owns the icons
* ``file`` - original input file before it has been modified by other hooks
**entity:<icon_type>:save, <entity_type>**
Triggered by ``ElggEntity::saveIcon*()`` methods and can be used to apply custom image manipulation logic to
resizing/cropping icons. The handler must return ``true`` to prevent the core APIs from resizing/cropping icons.
The ``$params`` array contains:
* ``entity`` - entity that owns the icons
* ``file`` - ``ElggFile`` object that points to the image file to be used as source for icons
* ``x1``, ``y1``, ``x2``, ``y2`` - cropping coordinates
**entity:<icon_type>:saved, <entity_type>**
Triggered by ``ElggEntity::saveIcon*()`` methods once icons have been created. This hook can be used by plugins
to create river items, update cropping coordinates for custom icon types etc. The handler can access the
created icons using ``ElggEntity::getIcon()``.
The ``$params`` array contains:
* ``entity`` - entity that owns the icons
* ``x1``, ``y1``, ``x2``, ``y2`` - cropping coordinates
**entity:<icon_type>:delete, <entity_type>**
Triggered by ``ElggEntity::deleteIcon()`` method and can be used for clean up operations. This hook is triggered
before the icons are deleted. The handler can return ``false`` to prevent icons from being deleted.
The ``$params`` array contains:
* ``entity`` - entity that owns the icons
**entity:url, <entity_type>**
Return the URL for the entity ``$params['entity']``. Note: Generally it is better to override the
``getUrl()`` method of ElggEntity. This hook should be used when it's not possible to subclass
View
@@ -18,6 +18,7 @@ Deprecated APIs
* ``elgg.ui.river`` JavaScript library: Remove calls to ``elgg_load_js('elgg.ui.river')`` from plugin code. Update ``core/river/filter`` and ``forms/comment/save``, if overwritten, to require component AMD modules
* ``elgg.ui.popupOpen()`` and ``elgg.ui.popupClose()`` methods in ``elgg.ui`` JS library: Use ``elgg/popup`` module instead.
* ``lightbox.js`` library: Do not use ``elgg_load_js('lightbox.js');`` unless your code references deprecated ``elgg.ui.lightbox`` namespace. Use ``elgg/lightbox`` AMD module instead.
* Accessing ``icons_sizes`` config value directly: Use ``elgg_get_icon_sizes()``
Deprecated Views
----------------
@@ -26,7 +27,7 @@ Deprecated Views
* ``lightbox/settings.js`` is deprecated: Use ``getOptions, ui.lightbox`` JS plugin hook or ``data-colorbox-opts`` attribute.
Added ``elgg/popup`` module
-----------------------------
---------------------------
New :doc:`elgg/popup module <javascript>` can be used to build out more complex trigger-popup interactions, including binding custom anchor types and opening/closing popups programmatically.
@@ -35,6 +36,19 @@ Added ``elgg/lightbox`` module
New :doc:`elgg/lightbox module <javascript>` can be used to open and close the lightbox programmatically.
New API for handling entity icons
---------------------------------
* ``ElggEntity`` now implements ``\Elgg\EntityIcon`` interface
* ``elgg_get_icon_sizes()`` - return entity type/subtype specific icon sizes
* ``ElggEntity::saveIconFromUploadedFile()`` - creates icons from an uploaded file
* ``ElggEntity::saveIconFromLocalFile()`` - creates icons from a local file
* ``ElggEntity::saveIconFromElggFile()`` - creates icons from an instance of ``ElggFile``
* ``ElggEntity::getIcon()`` - returns an instanceof ``ElggIcon`` that points to entity icon location on filestore (this may be just a placeholder, use ``ElggEntity::hasIcon()`` to validate if file has been written)
* ``ElggEntity::deleteIcon()`` - deletes entity icons
* ``ElggEntity::getIconLastChange()`` - return modified time of the icon file
* ``ElggEntity::hasIcon()`` - checks if an icon with given size has been created
From 2.0 to 2.1
===============
@@ -37,6 +37,7 @@
* @property-read \Elgg\Assets\ExternalFiles $externalFiles
* @property-read \ElggFileCache $fileCache
* @property-read \Elgg\PluginHooksService $hooks
* @property-read \Elgg\EntityIconService $iconService
* @property-read \Elgg\Http\Input $input
* @property-read \Elgg\Logger $logger
* @property-read Mailer $mailer
@@ -189,6 +190,10 @@ public function __construct(\Elgg\Config $config) {
return $this->resolveLoggerDependencies('hooks');
});
$this->setFactory('iconService', function(ServiceProvider $c) {
return new \Elgg\EntityIconService($c->config, $c->hooks, $c->request, $c->logger);
});
$this->setClassName('input', \Elgg\Http\Input::class);
$this->setFactory('logger', function(ServiceProvider $c) {
@@ -0,0 +1,84 @@
<?php
namespace Elgg;
/**
* Entities that support icons should implement this interface
*/
interface EntityIcon {
/**
* Saves icons using an uploaded file as the source.
*
* @param string $input_name Form input name
* @param string $type The name of the icon. e.g., 'icon', 'cover_photo'
* @param array $coords An array of cropping coordinates x1, y1, x2, y2
* @return bool
*/
public function saveIconFromUploadedFile($input_name, $type = 'icon', array $coords = array());
/**
* Saves icons using a local file as the source.
*
* @param string $filename The full path to the local file
* @param string $type The name of the icon. e.g., 'icon', 'cover_photo'
* @param array $coords An array of cropping coordinates x1, y1, x2, y2
* @return bool
*/
public function saveIconFromLocalFile($filename, $type = 'icon', array $coords = array());
/**
* Saves icons using a file located in the data store as the source.
*
* @param string $file An ElggFile instance
* @param string $type The name of the icon. e.g., 'icon', 'cover_photo'
* @param array $coords An array of cropping coordinates x1, y1, x2, y2
* @return bool
*/
public function saveIconFromElggFile(\ElggFile $file, $type = 'icon', array $coords = array());
/**
* Returns entity icon as an ElggIcon object
* The icon file may or may not exist on filestore
*
* @param string $size Size of the icon
* @param string $type The name of the icon. e.g., 'icon', 'cover_photo'
* @return \ElggIcon
*/
public function getIcon($size, $type = 'icon');
/**
* Removes all icon files and metadata for the passed type of icon.
*
* @param string $type The name of the icon. e.g., 'icon', 'cover_photo'
* @return bool
*/
public function deleteIcon($type = 'icon');
/**
* Returns a URL of the icon.
*
* @param array $params An array of paramaters including:
* string 'size' => the size of the icon (default: medium)
* string 'type' => the icon type (default: icon)
* @return string
*/
public function getIconURL($params);
/**
* Returns the timestamp of when the icon was changed.
*
* @param string $size The size of the icon
* @param string $type The name of the icon. e.g., 'icon', 'cover_photo'
*
* @return int|null A unix timestamp of when the icon was last changed, or null if not set.
*/
public function getIconLastChange($size, $type = 'icon');
/**
* Returns if the entity has an icon of the passed type.
*
* @param string $size The size of the icon
* @param string $type The name of the icon. e.g., 'icon', 'cover_photo'
* @return bool
*/
public function hasIcon($size, $type = 'icon');
}
Oops, something went wrong.

0 comments on commit 72b8a2c

Please sign in to comment.