1 <?php
2
3 class SortableDataObject extends DataObjectDecorator {
4
5 static $sortable_classes = array();
6 static $many_many_sortable_relations = array();
7 static $sort_dir = "ASC";
8
9 public static function set_sort_dir($dir) {
10 self::$sort_dir = $dir;
11 }
12
13
14 public static function add_sortable_class($className) {
15 if(!self::is_sortable_class($className)) {
16 DataObject::add_extension($className,'SortableDataObject');
17 self::$sortable_classes[] = $className;
18 }
19 }
20
21 public function () {
22 return array (
23 'db' => array (
24 'SortOrder' => 'Int'
25 )
26 );
27 }
28
29
30 public static function add_sortable_classes(array $classes) {
31 foreach($classes as $class)
32 self::add_sortable_class($class);
33 }
34
35 public static function add_sortable_many_many_relation($ownerClass,$componentName) {
36
37 list($parentClass, $componentClass, $parentField, $componentField, $table) = singleton($ownerClass)->many_many($componentName);
38 Object::add_static_var($ownerClass,'many_many_extraFields',array(
39 $componentName => array(
40 'SortOrder' => 'Int'
41 )));
42 if(!isset(self::$many_many_sortable_relations[$componentClass]))
43 self::$many_many_sortable_relations[$componentClass] = array();
44
45 self::$many_many_sortable_relations[$componentClass][$parentClass] = $table;
46 self::add_sortable_class($componentClass);
47 }
48
49 public static function remove_sortable_class($class) {
50 if(self::is_sortable_class($className)) {
51 Object::remove_extension($className, 'SortableDataObject');
52 if (($key = array_search($className, self::$sortable_classes)) !== false) {
53 array_splice(self::$sortable_classes, $key, 1);
54 }
55 }
56 }
57
58 public static function is_sortable_class($classname) {
59 if(in_array($classname, self::$sortable_classes))
60 return true;
61 foreach(self::$sortable_classes as $class) {
62 if(is_subclass_of($classname, $class))
63 return true;
64 }
65 return false;
66
67 }
68
69 public static function is_sortable_many_many($componentClass, $parentClass = null) {
70 $map = self::$many_many_sortable_relations;
71 if($parentClass === null)
72 return isset($map[$componentClass]);
73 else {
74 if(isset($map[$componentClass]))
75 return isset($map[$componentClass][$parentClass]);
76 return false;
77 }
78
79 }
80
81 public static function get_join_tables($classname) {
82 if(isset(self::$many_many_sortable_relations[$classname]))
83 return self::$many_many_sortable_relations[$classname];
84 return false;
85 }
86
87
88 public function augmentSQL(SQLQuery &$query) {
89 if(empty($query->select) || $query->delete) return;
90 $sort_field = false;
91 if($join_tables = self::get_join_tables($this->owner->class)) {
92 foreach($query->from as $from) {
93 if($sort_field) break;
94 foreach($join_tables as $join_table) {
95 if(stristr($from,$join_table)) {
96 $sort_field = "`$join_table`.SortOrder";
97 break;
98 }
99 }
100 }
101 }
102 if(!$sort_field) $sort_field = "SortOrder";
103
104 if(!$query->orderby || ($query->orderby == $this->owner->stat('default_sort')))
105 $query->orderby = "$sort_field " . self::$sort_dir;
106 }
107
108 public function onBeforeWrite() {
109 if(!$this->owner->ID && !$this->owner->SortOrder) {
110 $tables = DB::tableList();
111
112 $table = false;
113 foreach(self::$sortable_classes as $sortable_class) {
114 if (($sortable_class == $this->owner->class) || (ClassInfo::is_subclass_of($this->owner->class, $sortable_class))) {
115 $table = $sortable_class;
116 }
117 }
118 if ($table && isset($tables[strtolower($table)])) {
119 $this->owner->SortOrder = DB::query("select max(SortOrder) from {$table}")->value() + 1;
120 }
121 }
122 }
123
124 }
125
[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the
Silverstripe Forums to ask development related questions.
-