Permalink
Browse files

Initial commit of module

  • Loading branch information...
UndefinedOffset committed May 9, 2012
1 parent 0638c2d commit 710c7b88d2df485ed541fd47ab0b4872d9347415
View
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<buildpath>
+ <buildpathentry kind="con" path="org.eclipse.php.core.LANGUAGE"/>
+ <buildpathentry kind="src" path=""/>
+ <buildpathentry kind="con" path="ca.edchipman.silverstripepdt.LANGUAGE"/>
+</buildpath>
View
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>SortableGridField</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.wst.jsdt.core.javascriptValidator</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.wst.validation.validationbuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.dltk.core.scriptbuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>ca.edchipman.silverstripepdt.SilverStripeNature</nature>
+ <nature>org.eclipse.php.core.PHPNature</nature>
+ <nature>org.eclipse.wst.jsdt.core.jsNature</nature>
+ </natures>
+</projectDescription>
View
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="">
+ <attributes>
+ <attribute name="provider" value="org.eclipse.wst.jsdt.web.core.internal.project.ModuleSourcePathProvider"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.WebProject">
+ <attributes>
+ <attribute name="hide" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.baseBrowserLibrary"/>
+ <classpathentry kind="output" path=""/>
+</classpath>
@@ -0,0 +1,3 @@
+eclipse.preferences.version=1
+include_path=0;/SortableGridField\u00055;ca.edchipman.silverstripepdt.LANGUAGE
+silverstripe_version=SS2.4
@@ -0,0 +1 @@
+org.eclipse.wst.jsdt.launching.baseBrowserLibrary
@@ -0,0 +1 @@
+Window
View
@@ -0,0 +1,3 @@
+<?php
+
+?>
@@ -0,0 +1,135 @@
+<?php
+class GridFieldSortableObject extends DataExtension {
+ public static $db=array(
+ 'SortOrder'=>'Int'
+ );
+
+ protected static $sortable_classes = array();
+ protected static $many_many_sortable_relations = array();
+ protected static $sort_dir = "ASC";
+
+
+ public static function set_sort_dir($dir) {
+ self::$sort_dir=$dir;
+ }
+
+
+ public static function add_sortable_class($className) {
+ if(!self::is_sortable_class($className)) {
+ Object::add_extension($className, 'GridFieldSortableObject');
+
+ self::$sortable_classes[]=$className;
+ }
+ }
+
+ public static function add_sortable_classes(array $classes) {
+ foreach($classes as $class) {
+ self::add_sortable_class($class);
+ }
+ }
+
+ public static function add_sortable_many_many_relation($ownerClass, $componentName) {
+ list($parentClass, $componentClass, $parentField, $componentField, $table)=singleton($ownerClass)->many_many($componentName);
+
+ Object::add_static_var($ownerClass, 'many_many_extraFields', array(
+ $componentName=>array(
+ 'SortOrder'=>'Int'
+ )));
+
+
+ if(!isset(self::$many_many_sortable_relations[$componentClass])) {
+ self::$many_many_sortable_relations[$componentClass] = array();
+ }
+
+
+ self::$many_many_sortable_relations[$componentClass][$parentClass]=$table;
+ self::add_sortable_class($componentClass);
+ }
+
+ public static function remove_sortable_class($class) {
+ Object::remove_extension($class, 'GridFieldSortableObject');
+ }
+
+ public static function is_sortable_class($classname) {
+ if(in_array($classname, self::$sortable_classes)) {
+ return true;
+ }
+
+ foreach(self::$sortable_classes as $class) {
+ if(is_subclass_of($classname, $class)) {
+ return true;
+ }
+ }
+
+
+ return Object::has_extension($classname, 'GridFieldSortableObject');
+ }
+
+ public static function is_sortable_many_many($componentClass, $parentClass=null) {
+ $map=self::$many_many_sortable_relations;
+ if($parentClass===null) {
+ return isset($map[$componentClass]);
+ }else {
+ if(isset($map[$componentClass])) {
+ return isset($map[$componentClass][$parentClass]);
+ }
+
+ return false;
+ }
+
+ }
+
+ public static function get_join_tables($classname) {
+ if(isset(self::$many_many_sortable_relations[$classname])) {
+ return self::$many_many_sortable_relations[$classname];
+ }
+
+ return false;
+ }
+
+ public function augmentSQL(SQLQuery &$query) {
+ if(empty($query->select) || $query->delete || in_array("COUNT(*)", $query->select) || in_array("count(*)", $query->select)) {
+ return;
+ }
+
+
+ $sort_field=false;
+ if($join_tables=self::get_join_tables($this->owner->class)) {
+ foreach($query->from as $from) {
+ if($sort_field) {
+ break;
+ }
+
+ foreach($join_tables as $join_table) {
+ if(stristr($from,$join_table)) {
+ $sort_field="\"$join_table\".\"SortOrder\"";
+
+ if(isset($query->select['SortOrder'])) {
+ $query->select['SortOrder']="\"{$this->owner->class}\".SortOrder AS LocalSort";
+ }
+
+ break;
+ }
+ }
+ }
+ }
+
+
+ if(!$sort_field) {
+ $sort_field="\"SortOrder\"";
+ }
+
+ if(!$query->orderby || ($query->orderby==$this->owner->stat('default_sort'))) {
+ $query->orderby="$sort_field ".self::$sort_dir;
+ }
+ }
+
+ public function onBeforeWrite() {
+ if(!$this->owner->ID) {
+ if($peers=DataList::create($this->owner->class)) {
+ $this->owner->SortOrder=$peers->Count()+1;
+ }
+ }
+ }
+}
+?>
@@ -0,0 +1,143 @@
+<?php
+/**
+ * @package forms
+ */
+class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionProvider {
+ /**
+ * Returns a map where the keys are fragment names and the values are pieces of HTML to add to these fragments.
+ * @param GridField $gridField Grid Field Reference
+ * @return {array} Map where the keys are fragment names and the values are pieces of HTML to add to these fragments.
+ */
+ public function getHTMLFragments($gridField) {
+ $state=$gridField->State->GridFieldSortableRows;
+ if(!is_bool($state->sortableToggle)) {
+ $state->sortableToggle=false;
+ }
+
+
+
+ if(Object::has_extension($gridField->getModelClass(), 'GridFieldSortableObject')) {
+ //Sort order toggle
+ $sortOrderToggle=new GridField_FormAction($gridField, 'sortablerows_toggle', 'Allow drag and drop re-ordering', 'saveGridRowSort', null);
+ $sortOrderToggle->addExtraClass('sortablerows_toggle');
+
+ //Disable Pagenator
+ if($gridField->getConfig()->getComponentByType('GridFieldPaginator')) {
+ $disablePagenator=new GridField_FormAction($gridField, 'sortablerows_disablepagenator', 'Disable Pagenator', 'sortableRowsDisablePaginator', null);
+ $disablePagenator->addExtraClass('sortablerows_disablepagenator');
+ }else {
+ $disablePagenator=null;
+ }
+
+ $forTemplate=new ArrayData(array(
+ 'SortableToggle'=>$sortOrderToggle,
+ 'PagenatorToggle'=>$disablePagenator,
+ 'Checked'=>($state->sortableToggle==true ? ' checked="checked"':'')
+ ));
+
+
+ //Inject Requirements
+ Requirements::css('SortableGridField/css/GridFieldSortableRows.css');
+ Requirements::javascript('SortableGridField/javascript/GridFieldSortableRows.js');
+
+
+ return array(
+ 'header'=>$forTemplate->renderWith('GridFieldSortableRows', array('Colspan'=>count($gridField->getColumns())))
+ );
+ }
+
+ return array();
+ }
+
+ /**
+ * Return a list of the actions handled by this action provider.
+ * @param GridField $gridField Grid Field Reference
+ * @return {array} Array with action identifier strings.
+ */
+ public function getActions($gridField) {
+ if(Object::has_extension($gridField->getModelClass(), 'GridFieldSortableObject')) {
+ if($gridField->getConfig()->getComponentByType('GridFieldPaginator')) {
+ return array('saveGridRowSort', 'sortableRowsDisablePaginator');
+ }else {
+ return array('saveGridRowSort');
+ }
+ }
+
+ return array();
+ }
+
+ /**
+ * Handle an action on the given grid field.
+ * @param {GridField} $gridField Grid Field Reference
+ * @param {string} $actionName Action identifier, see {@link getActions()}.
+ * @param {array} $arguments Arguments relevant for this
+ * @param {array} $data All form data
+ */
+ public function handleAction(GridField $gridField, $actionName, $arguments, $data) {
+ $state=$gridField->State->GridFieldSortableRows;
+ if(!is_bool($state->sortableToggle)) {
+ $state->sortableToggle=false;
+ }else if($state->sortableToggle==true) {
+ if($gridField->getConfig()->getComponentsByType('GridFieldPaginator')) {
+ $gridField->getConfig()->removeComponentsByType('GridFieldPaginator');
+ $gridField->getConfig()->addComponent(new GridFieldFooter());
+ }
+
+ $gridField->getConfig()->removeComponentsByType('GridFieldFilterHeader');
+ $gridField->getConfig()->removeComponentsByType('GridFieldSortableHeader');
+ }
+
+
+ if(Object::has_extension($gridField->getModelClass(), 'GridFieldSortableObject')) {
+ if($actionName=='savegridrowsort') {
+ return $this->saveGridRowSort($gridField, $data);
+ }
+ }
+ }
+
+ /**
+ * Handles saving of the row sort order
+ * @param {GridField} $gridField Grid Field Reference
+ * @param {array} $data Data submitted in the request
+ */
+ private function saveGridRowSort(GridField $gridField, $data) {
+ if(empty($data['Items'])) {
+ user_error('No items to sort', E_USER_ERROR);
+ }
+
+ $className=$gridField->getModelClass();
+ $ownerClass=$gridField->Form->Controller()->class;
+
+ $many_many=GridFieldSortableObject::is_sortable_many_many($className);
+ if($many_many) {
+ $candidates=singleton($ownerClass)->many_many();
+ if(is_array($candidates)) {
+ foreach($candidates as $name => $class)
+ if($class==$className) {
+ $relationName=$name;
+ break;
+ }
+ }
+
+ if(!isset($relationName)) {
+ return false;
+ }
+
+ list($parentClass, $componentClass, $parentField, $componentField, $table)=singleton($ownerClass)->many_many($relationName);
+ }
+
+
+ $data['Items']=explode(',', $data['Items']);
+ for($sort=0;$sort<count($data['Items']);$sort++) {
+ $id=intval($data['Items'][$sort]);
+ if($many_many) {
+ DB::query("UPDATE \"$table\" SET \"SortOrder\" = $sort WHERE \"{$className}ID\" = $id");
+ }else {
+ $obj=DataObject::get_by_id($className, $id);
+ $obj->SortOrder=$sort;
+ $obj->write();
+ }
+ }
+ }
+}
+?>
@@ -0,0 +1,7 @@
+.cms table.ss-gridfield-table thead tr th.sortablerowsheading {
+ border-bottom: 1px solid rgba(0, 0, 0, 0.1);
+}
+
+.cms table.ss-gridfield-table thead tr th.sortablerowsheading .gridfield-sortablerows button {
+ display: none;
+}
Oops, something went wrong.

0 comments on commit 710c7b8

Please sign in to comment.