aboutsummaryrefslogtreecommitdiff
path: root/src/SortByFieldExtension.php
diff options
context:
space:
mode:
Diffstat (limited to 'src/SortByFieldExtension.php')
-rw-r--r--src/SortByFieldExtension.php82
1 files changed, 82 insertions, 0 deletions
diff --git a/src/SortByFieldExtension.php b/src/SortByFieldExtension.php
new file mode 100644
index 0000000..a3e028b
--- /dev/null
+++ b/src/SortByFieldExtension.php
@@ -0,0 +1,82 @@
+<?php
+
+namespace Snilius\Twig;
+use Exception;
+
+/**
+ * User: Victor Häggqvist
+ * Date: 3/4/15
+ * Time: 2:07 AM
+ *
+ * The base of the filter is borrowed from https://github.com/dannynimmo/craftcms-sortbyfield
+ *
+ * I hav extended it to also sort array structures
+ */
+
+class SortByFieldExtension extends \Twig_Extension {
+
+ public function getName() {
+ return 'sortbyfield';
+ }
+
+ public function getFilters() {
+ return array(
+ new \Twig_SimpleFilter('sortbyfield', array($this, 'sortByFieldFilter'))
+ );
+ }
+ /**
+ * The "sortByField" filter sorts an array of entries (objects or arrays) by the specified field's value
+ *
+ * Usage: {% for entry in master.entries|sortbyfield('ordering', 'desc') %}
+ */
+ public function sortByFieldFilter($content, $sort_by = null, $direction = 'asc') {
+ if (!is_array($content)) {
+ throw new \InvalidArgumentException('Variable passed to the sortByField filter is not an array');
+ } elseif ($sort_by === null) {
+ throw new Exception('No sort by parameter passed to the sortByField filter');
+ } elseif (!self::isSortable($content[0], $sort_by)) {
+ throw new Exception('Entries passed to the sortByField filter do not have the field "' . $sort_by . '"');
+ } else {
+ // Unfortunately have to suppress warnings here due to __get function
+ // causing usort to think that the array has been modified:
+ // usort(): Array was modified by the user comparison function
+ @usort($content, function ($a, $b) use($sort_by, $direction) {
+ $flip = ($direction === 'desc') ? -1 : 1;
+
+ if (is_array($a))
+ $a_sort_value = $a[$sort_by];
+ else
+ $a_sort_value = $a->$sort_by;
+
+ if (is_array($b))
+ $b_sort_value = $b[$sort_by];
+ else
+ $b_sort_value = $b->$sort_by;
+
+ if($a_sort_value == $b_sort_value) {
+ return 0;
+ } else if($a_sort_value > $b_sort_value) {
+ return (1 * $flip);
+ } else {
+ return (-1 * $flip);
+ }
+ });
+ }
+ return $content;
+ }
+
+ /**
+ * Validate the passed $item to check if it can be sorted
+ * @param $item mixed Collection item to be sorted
+ * @param $field string
+ * @return bool If collection item can be sorted
+ */
+ private static function isSortable($item, $field) {
+ if (is_array($item))
+ return array_key_exists($field, $item);
+ elseif (is_object($item))
+ return property_exists($item, $field);
+ else
+ return false;
+ }
+}