Version: current

      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 extraStatics() {
     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             // определяем базовую таблицу объекта (с полем SortOrder)
    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. -