Browse Source

Improving work UI see BT#6418

Julio Montoya 11 years ago
parent
commit
c428de9da1

+ 14 - 4
main/inc/ajax/model.ajax.php

@@ -208,7 +208,16 @@ switch ($action) {
 
         if (empty($documents)) {
             $whereCondition .= " AND u.user_id = ".api_get_user_id();
-            $count = get_work_user_list(0, $limit, $sidx, $sord, $work_id, $whereCondition, null, true);
+            $count = get_work_user_list(
+                0,
+                $limit,
+                $sidx,
+                $sord,
+                $work_id,
+                $whereCondition,
+                null,
+                true
+            );
         } else {
             $count = get_work_user_list_from_documents(
                 0,
@@ -235,8 +244,8 @@ switch ($action) {
             api_get_group_id(),
             0,
             $limit,
-            $sidx,
-            $sord,
+            null,
+            null,
             true
         );
         break;
@@ -492,7 +501,8 @@ switch ($action) {
         }
         break;
     case 'get_work_teacher':
-        $columns = array('type', 'title', 'sent_date', 'expires_on', 'ends_on', 'actions');
+        //$columns = array('type', 'title', 'sent_date', 'expires_on', 'ends_on', 'actions');
+        $columns = array('type', 'title', 'sent_date', 'expires_on', 'amount', 'actions');
         $result = getWorkListTeacher($start, $limit, $sidx, $sord, $whereCondition);
         break;
     case 'get_work_student':

+ 80 - 0
main/inc/lib/formvalidator/Element/DateTimePicker.php

@@ -0,0 +1,80 @@
+<?php
+/* For licensing terms, see /license.txt */
+require_once 'HTML/QuickForm/date.php';
+
+/**
+ * Form element to select a date and hour (with popup datepicker)
+ */
+class DateTimePicker extends HTML_QuickForm_text
+{
+    public $addLibrary = false;
+	/**
+	 * Constructor
+	 */
+	public function DateTimePicker($elementName = null, $elementLabel = null, $attributes = null)
+	{
+        if (!isset($attributes['id'])) {
+            $attributes['id'] = $elementName;
+        }
+
+		HTML_QuickForm_element::HTML_QuickForm_element($elementName, $elementLabel, $attributes);
+		$this->_appendName = true;
+		$this->_type = 'datetimepicker';
+	}
+
+	/**
+	 * HTML code to display this datepicker
+	 */
+	public function toHtml()
+	{
+		$js = $this->getElementJS();
+		return $js.parent::toHtml();
+	}
+
+    function setValue($value)
+    {
+        $value = substr($value, 0, 16);
+        $this->updateAttributes(
+            array(
+                'value'=>$value
+            )
+        );
+    }
+
+	/**
+	 * Get the necessary javascript for this datepicker
+	 */
+	private function getElementJS()
+	{
+        $js = null;
+
+        if ($this->addLibrary == true) {
+            $js .= '<script src="'.api_get_path(WEB_LIBRARY_PATH).'javascript/datetimepicker/jquery-ui-timepicker-addon.js" type="text/javascript"></script>';
+            $js .='<link  href="'.api_get_path(WEB_LIBRARY_PATH).'javascript/datetimepicker/jquery-ui-timepicker-addon.css" rel="stylesheet" type="text/css" />';
+
+            $isocode = api_get_language_isocode();
+            if ($isocode != 'en') {
+                $js .= '<script src="'.api_get_path(WEB_LIBRARY_PATH).'javascript/datetimepicker/i18n/jquery-ui-timepicker-'.$isocode.'.js" type="text/javascript"></script>';
+
+                $js .= api_get_js('jquery-ui/jquery-ui-i18n.min.js');
+                $js .= '<script>
+                $(function(){
+                    $.datepicker.setDefaults($.datepicker.regional["'.$isocode.'"]);
+                });
+                </script>';
+            }
+        }
+
+        $id = $this->getAttribute('id');
+        //timeFormat: 'hh:mm'
+        $js .= "<script>
+            $(function() {
+                $('#$id').datetimepicker({
+                    dateFormat: 'yy-mm-dd'
+                });
+            });
+        </script>";
+		return $js;
+	}
+
+}

+ 5 - 4
main/inc/lib/formvalidator/FormValidator.class.php

@@ -1,8 +1,8 @@
 <?php
 /* For licensing terms, see /license.txt */
 
-require_once api_get_path(LIBRARY_PATH) . 'pear/HTML/QuickForm.php';
-require_once api_get_path(LIBRARY_PATH) . 'pear/HTML/QuickForm/advmultiselect.php';
+require_once api_get_path(LIBRARY_PATH).'pear/HTML/QuickForm.php';
+require_once api_get_path(LIBRARY_PATH).'pear/HTML/QuickForm/advmultiselect.php';
 
 /**
  * Filter
@@ -125,6 +125,8 @@ class FormValidator extends HTML_QuickForm
         // Load some custom elements and rules
         $dir = api_get_path(LIBRARY_PATH) . 'formvalidator/';
         $this->registerElementType('html_editor', $dir . 'Element/html_editor.php', 'HTML_QuickForm_html_editor');
+
+        $this->registerElementType('datetimepicker', $dir . 'Element/DateTimePicker.php', 'DateTimePicker');
         $this->registerElementType('datepicker', $dir . 'Element/datepicker.php', 'HTML_QuickForm_datepicker');
         $this->registerElementType('datepickerdate', $dir . 'Element/datepickerdate.php', 'HTML_QuickForm_datepickerdate');
         $this->registerElementType('receivers', $dir . 'Element/receivers.php', 'HTML_QuickForm_receivers');
@@ -234,7 +236,7 @@ EOT;
     }
 
     /**
-     * Adds a textfield to the form.
+     * Adds a text field to the form.
      * A trim-filter is attached to the field.
      * @param string $label						The label for the form-element
      * @param string $name						The element name
@@ -433,7 +435,6 @@ EOT;
      */
     function add_real_progress_bar($upload_id, $element_after, $delay = 2, $wait_after_upload = false)
     {
-
         if (!function_exists('uploadprogress_get_info')) {
             $this->add_progress_bar($delay);
             return;

+ 7 - 4
main/inc/lib/main_api.lib.php

@@ -6049,7 +6049,7 @@ function api_get_jquery_libraries_js($libraries) {
     }
 
     // jquery datepicker
-    if (in_array('datepicker',$libraries)) {
+    if (in_array('datepicker', $libraries)) {
         $languaje   = 'en-GB';
         $platform_isocode = strtolower(api_get_language_isocode());
 
@@ -6061,6 +6061,7 @@ function api_get_jquery_libraries_js($libraries) {
             $languaje = $platform_isocode;
         }
 
+        $js .= api_get_js('jquery-ui/jquery-ui-i18n.min.js');
         $script = '<script>
         $(function(){
             $.datepicker.setDefaults($.datepicker.regional["'.$languaje.'"]);
@@ -6068,8 +6069,8 @@ function api_get_jquery_libraries_js($libraries) {
         });
         </script>
         ';
-        $js .= api_get_js('jquery-ui/jquery-ui-i18n.min.js');
-        $js .= $script; //api_get_js('jquery-ui/ui/i18n/jquery.ui.datepicker-'.$languaje.'.js');
+        $js .= $script;
+
 
     }
     return $js;
@@ -6451,12 +6452,13 @@ function api_get_security_key() {
 }
 
 function api_get_datetime_picker_js($htmlHeadXtra) {
+
     $htmlHeadXtra[] = '<script src="'.api_get_path(WEB_LIBRARY_PATH).'javascript/datetimepicker/jquery-ui-timepicker-addon.js" type="text/javascript" language="javascript"></script>';
     $htmlHeadXtra[] = '<link  href="'.api_get_path(WEB_LIBRARY_PATH).'javascript/datetimepicker/jquery-ui-timepicker-addon.css" rel="stylesheet" type="text/css" />';
 
     $isocode = api_get_language_isocode();
     if ($isocode != 'en') {
-        $htmlHeadXtra[] = '<script src="'.api_get_path(WEB_LIBRARY_PATH).'javascript/datetimepicker/localization/jquery-ui-timepicker-'.$isocode.'.js" type="text/javascript" language="javascript"></script>';
+        $htmlHeadXtra[] = '<script src="'.api_get_path(WEB_LIBRARY_PATH).'javascript/datetimepicker/i18n/jquery-ui-timepicker-'.$isocode.'.js" type="text/javascript" language="javascript"></script>';
     }
     return $htmlHeadXtra;
 }
@@ -6872,6 +6874,7 @@ function api_remove_tags_with_space($in_html, $in_double_quote_replace = true) {
     // avoid text stuck together when tags are removed, adding a space after >
     $out_res = str_replace (">", "> ", $out_res);
     $out_res = strip_tags($out_res);
+
     return $out_res;
 }
 

+ 11 - 8
main/inc/lib/pear/HTML/QuickForm.php

@@ -38,8 +38,7 @@ require_once 'HTML/Common.php';
  *      HTML_QuickForm::isTypeRegistered()
  * @global array $GLOBALS['HTML_QUICKFORM_ELEMENT_TYPES']
  */
-$GLOBALS['HTML_QUICKFORM_ELEMENT_TYPES'] =
-array(
+$GLOBALS['HTML_QUICKFORM_ELEMENT_TYPES'] = array(
     'group'             => array('HTML/QuickForm/group.php','HTML_QuickForm_group'),
     'hidden'            => array('HTML/QuickForm/hidden.php','HTML_QuickForm_hidden'),
     'reset'             => array('HTML/QuickForm/reset.php','HTML_QuickForm_reset'),
@@ -132,7 +131,7 @@ define('QUICKFORM_INVALID_DATASOURCE',     -9);
  */
 class HTML_QuickForm extends HTML_Common
 {
-    // {{{ properties
+    private $dateTimePickerLibraryAdded;
 
     /**
      * Array containing the form fields
@@ -294,10 +293,7 @@ class HTML_QuickForm extends HTML_Common
     {
         HTML_Common::HTML_Common($attributes);
         $method = (strtoupper($method) == 'GET') ? 'get' : 'post';
-        // Modified by Chamilo team, 16-MAR-2010
-        //$action = ($action == '') ? $_SERVER['PHP_SELF'] : $action;
         $action = ($action == '') ? api_get_self() : $action;
-        //
         $target = empty($target) ? array() : array('target' => $target);
         $form_id = $formName;
         if (isset($attributes['id']) && !empty($attributes['id'])) {
@@ -665,11 +661,18 @@ class HTML_QuickForm extends HTML_Common
             }
         }
         $elementName = $elementObject->getName();
+        $type = $elementObject->getType();
+
+        if ($type == 'datetimepicker' && $this->dateTimePickerLibraryAdded == false) {
+            $elementObject->addLibrary = true;
+            $this->dateTimePickerLibraryAdded = true;
+        } else {
+            $elementObject->addLibrary = false;
+        }
 
         // Add the element if it is not an incompatible duplicate
         if (!empty($elementName) && isset($this->_elementIndex[$elementName])) {
-            if ($this->_elements[$this->_elementIndex[$elementName]]->getType() == $elementObject->getType()
-            ) {
+            if ($this->_elements[$this->_elementIndex[$elementName]]->getType() == $elementObject->getType()) {
                 $this->_elements[] =& $elementObject;
                 $elKeys = array_keys($this->_elements);
                 $this->_duplicateIndex[$elementName][] = end($elKeys);

+ 8 - 37
main/inc/lib/pear/HTML/QuickForm/Rule/CompareDate.php

@@ -36,44 +36,15 @@ require_once 'HTML/QuickForm/Rule.php';
  */
 class HTML_QuickForm_Rule_CompareDate extends HTML_QuickForm_Rule
 {
-   /**
-    * Possible operators to use
-    * @var array
-    * @access private
-    */
-    /*var $_operators = array(
-        'eq'  => '==',
-        'neq' => '!=',
-        'gt'  => '>',
-        'gte' => '>=',
-        'lt'  => '<',
-        'lte' => '<='
-    );*/
-
-
-   /**
-    * Returns the operator to use for comparing the values
-    *
-    * @access private
-    * @param  string     operator name
-    * @return string     operator to use for validation
-    */
-    /*function _findOperator($name)
+    function validate($values, $options)
     {
-        if (empty($name)) {
-            return '==';
-        } elseif (isset($this->_operators[$name])) {
-            return $this->_operators[$name];
-        } elseif (in_array($name, $this->_operators)) {
-            return $name;
+        if (!is_array($values[0]) && !is_array($values[1])) {
+            return api_strtotime($values[0]) < api_strtotime($values[1]);
         } else {
-            return '==';
+            $compareFn = create_function(
+                '$a, $b', 'return mktime($a[\'H\'],$a[\'i\'],0,$a[\'M\'],$a[\'d\'],$a[\'Y\']) <=   mktime($b[\'H\'],$b[\'i\'],0,$b[\'M\'],$b[\'d\'],$b[\'Y\'] );'
+            );
+            return $compareFn($values[0], $values[1]);
         }
-    }*/
-
-    function validate($values, $options)
-    {
-        $compareFn = create_function('$a, $b', 'return mktime($a[\'H\'],$a[\'i\'],0,$a[\'M\'],$a[\'d\'],$a[\'Y\']) <=   mktime($b[\'H\'],$b[\'i\'],0,$b[\'M\'],$b[\'d\'],$b[\'Y\'] );');
-        return $compareFn($values[0], $values[1]);
     }
-}
+}

+ 4 - 16
main/inc/lib/pear/HTML/QuickForm/element.php

@@ -403,10 +403,7 @@ class HTML_QuickForm_element extends HTML_Common
                 $this->setValue($arg);
         }
         return true;
-    } // end func onQuickFormEvent
-
-    // }}}
-    // {{{ accept()
+    }
 
    /**
     * Accepts a renderer
@@ -420,10 +417,7 @@ class HTML_QuickForm_element extends HTML_Common
     function accept(&$renderer, $required=false, $error=null)
     {
         $renderer->renderElement($this, $required, $error);
-    } // end func accept
-
-    // }}}
-    // {{{ _generateId()
+    }
 
    /**
     * Automatically generates and assigns an 'id' attribute for the element.
@@ -441,10 +435,7 @@ class HTML_QuickForm_element extends HTML_Common
         if (!$this->getAttribute('id')) {
             $this->updateAttributes(array('id' => 'qf_' . substr(md5(microtime() . $idx++), 0, 6)));
         }
-    } // end func _generateId
-
-    // }}}
-    // {{{ exportValue()
+    }
 
    /**
     * Returns a 'safe' element's value
@@ -495,7 +486,4 @@ class HTML_QuickForm_element extends HTML_Common
             }
         }
     }
-
-    // }}}
-} // end class HTML_QuickForm_element
-?>
+}

+ 44 - 0
main/template/default/work/comments.tpl

@@ -0,0 +1,44 @@
+
+{# "UpdatedBy"|get_lang|format(comment.username) #}
+
+{% if work_comment_enabled %}
+    <hr>
+    <h4>
+        {{ 'Comments' | get_lang }}
+    </h4>
+    <hr>
+    <ul>
+        {% for comment in comments %}
+            <li>
+                <div class="page-header">
+                    <a href="{{ _p.web_code }}">
+                        <img height="24" src="{{ comment.picture }}"/> {{ comment.username }}
+                    </a>- {{ comment.sent_at | api_get_local_time }}
+                </div>
+                <p>
+                    {% if comment.comment is not empty %}
+                        {{ comment.comment }}
+                    {% else %}
+                        {{ 'HereIsYourFeedback' | get_lang }}
+                    {% endif %}
+                </p>
+                {% if comment.file_url is not empty %}
+                    <p>
+                        <a href="{{ comment.file_url }}">
+                            <img src="{{ "attachment.gif"|icon(32) }}">
+                            {{ comment.file_name_to_show }}
+                        </a>
+                        {% if is_allowed_to_edit %}
+                            <a href="{{ comment.delete_file_url }}">
+                                <img src="{{ "delete.png"|icon(22) }}">
+                            </a>
+                        {% endif %}
+                    </p>
+                {% endif %}
+            </li>
+        {% endfor %}
+    </ul>
+    <br />
+    <hr>
+    {{ form }}
+{% endif %}

+ 15 - 42
main/template/default/work/view.tpl

@@ -1,49 +1,22 @@
 <div class="page-header">
-    <h2>{{ work.title }}</h2>
+    <h2>
+        {{ work.title }}
+        {% if work.contains_file %}
+            <a href="{{ work.download_url }}"><img src="{{ "save.png"|icon(22) }}"></a>
+        {% endif %}
+        </h2>
 </div>
+
+{% if work.description %}
 <p>
     {{ work.description }}
 </p>
-{# "UpdatedBy"|get_lang|format(comment.username) #}
+{% endif %}
 
-{% if work_comment_enabled %}
-    <hr>
-    <h4>
-        {{ 'Comments' | get_lang }}
-    </h4>
-    <hr>
-    <ul>
-    {% for comment in comments %}
-        <li>
-            <div class="page-header">
-                <a href="{{ _p.web_code }}">
-                    <img height="24" src="{{ comment.picture }}"/> {{ comment.username }}
-                </a>- {{ comment.sent_at | api_get_local_time }}
-            </div>
-            <p>
-                {% if comment.comment is not empty %}
-                    {{ comment.comment }}
-                {% else %}
-                    {{ 'HereIsYourFeedback' | get_lang }}
-                {% endif %}
-            </p>
-            {% if comment.file_url is not empty %}
-                <p>
-                    <a href="{{ comment.file_url }}">
-                        <img src="{{ "attachment.gif"|icon(32) }}">
-                        {{ comment.file_name_to_show }}
-                    </a>
-                    {% if is_allowed_to_edit %}
-                        <a href="{{ comment.delete_file_url }}">
-                            <img src="{{ "delete.png"|icon(22) }}">
-                        </a>
-                    {% endif %}
-                </p>
-            {% endif %}
-        </li>
-    {% endfor %}
-    </ul>
-    <br />
-    <hr>
-    {{ form }}
+{% if work.contains_file and work.show_content %}
+<p>
+    {{ work.show_content }}
+</p>
 {% endif %}
+
+{% include 'default/work/comments.tpl' %}

+ 3 - 65
main/work/download.php

@@ -26,71 +26,9 @@ if (empty($course_info)) {
     api_not_allowed(true);
 }
 
-$tbl_student_publication = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
-
-if (!empty($course_info['real_id'])) {
-    $sql = 'SELECT * FROM '.$tbl_student_publication.'
-            WHERE c_id = '.$course_info['real_id'].' AND id = "'.$id.'"';
-    $result = Database::query($sql);
-    if ($result && Database::num_rows($result)) {
-        $row = Database::fetch_array($result, 'ASSOC');
-        $full_file_name = api_get_path(SYS_COURSE_PATH).api_get_course_path().'/'.$row['url'];
-
-        $item_info = api_get_item_property_info(api_get_course_int_id(), 'work', $row['id']);
-
-        allowOnlySubscribedUser(api_get_user_id(), $row['parent_id'], $course_info['real_id']);
-
-        if (empty($item_info)) {
-            api_not_allowed();
-        }
-
-        /*
-        field show_score in table course :  0 => 	New documents are visible for all users
-                                            1 =>    New documents are only visible for the teacher(s)
-        field visibility in table item_property :   0 => eye closed, invisible for all students
-                                                    1 => eye open
-        field accepted in table c_student_publication : 0 => eye closed, invisible for all students
-                                                        1 => eye open
-        (we should have visibility == accepted , otherwise there is an inconsistency in the Database)
-        field value in table c_course_setting :     0 => Allow learners to delete their own publications = NO
-                                                    1 => Allow learners to delete their own publications = YES
-
-        +------------------+------------------------------+----------------------------+
-        |Can download work?|      doc visible for all = 0 |     doc visible for all = 1|
-        +------------------+------------------------------+----------------------------+
-        |  visibility = 0  | editor only                  | editor only                |
-        |                  |                              |                            |
-        +------------------+------------------------------+----------------------------+
-        |  visibility = 1  | editor                       | editor                     |
-        |                  | + owner of the work          | + any student              |
-        +------------------+------------------------------+----------------------------+
-        (editor = teacher + admin + anybody with right api_is_allowed_to_edit)
-        */
-
-        $work_is_visible = ($item_info['visibility'] == 1 && $row['accepted'] == 1);
-        $doc_visible_for_all = ($course_info['show_score'] == 1);
-
-        $is_editor = api_is_allowed_to_edit(true, true, true);
-        $student_is_owner_of_work = user_is_author($row['id'], $row['user_id']);
-
-        if ($is_editor || ($student_is_owner_of_work) || ($doc_visible_for_all && $work_is_visible)) {
-
-            $title = $row['title'];
-
-            if (array_key_exists('filename', $row) && !empty($row['filename'])) {
-                $title = $row['filename'];
-            }
-
-            $title = str_replace(' ', '_', $title);
-            event_download($title);
-            if (Security::check_abs_path($full_file_name, api_get_path(SYS_COURSE_PATH).api_get_course_path().'/')) {
-                DocumentManager::file_send_for_download($full_file_name, true, $title);
-            }
-        } else {
-            api_not_allowed();
-        }
-    }
-} else {
+$result = downloadFile($id, $course_info);
+if ($result == false) {
     api_not_allowed();
 }
+
 exit;

+ 18 - 8
main/work/edit.php

@@ -246,28 +246,38 @@ if ($form->validate()) {
 }
 
 $htmlHeadXtra[] = to_javascript_work();
-Display :: display_header(null);
 
+$tpl = new Template();
+$content = null;
 if (!empty($work_id)) {
     if ($is_allowed_to_edit) {
         if (api_resource_is_locked_by_gradebook($work_id, LINK_STUDENTPUBLICATION)) {
             echo Display::display_warning_message(get_lang('ResourceLockedByGradebook'));
         } else {
-            $form->display();
+
+            $comments = getWorkComments($my_folder_data);
+
+            $template = $tpl->get_template('work/comments.tpl');
+            $tpl->assign('work_comment_enabled', ALLOW_USER_COMMENTS);
+            $tpl->assign('comments', $comments);
+
+            $content .= $form->return_form();
+            $content  .= $tpl->fetch($template);
         }
     } elseif ($is_author) {
         if (empty($work_item['qualificator_id']) || $work_item['qualificator_id'] == 0) {
-            $form->display();
+            $content .= $form->return_form();
         } else {
-            Display::display_error_message(get_lang('ActionNotAllowed'));
+            $content .= Display::return_message(get_lang('ActionNotAllowed'), 'error');
         }
     } elseif ($student_can_edit_in_session && $has_ended == false) {
-        $form->display();
+        $content .= $form->return_form();
     } else {
-        Display::display_error_message(get_lang('ActionNotAllowed'));
+        $content .= Display::return_message(get_lang('ActionNotAllowed'), 'error');
     }
 } else {
-    Display::display_error_message(get_lang('ActionNotAllowed'));
+    $content .= Display::return_message(get_lang('ActionNotAllowed'), 'error');
 }
 
-Display :: display_footer();
+$tpl->assign('content', $content);
+$tpl->display_one_col_template();

+ 23 - 23
main/work/edit_work.php

@@ -1,5 +1,6 @@
 <?php
 /* For licensing terms, see /license.txt */
+use ChamiloSession as Session;
 
 $language_file = array('exercice', 'work', 'document', 'admin', 'gradebook');
 
@@ -10,7 +11,6 @@ $lib_path = api_get_path(LIBRARY_PATH);
 require_once $lib_path.'fileManage.lib.php';
 require_once 'work.lib.php';
 
-
 // Section (for the tabs)
 $this_section = SECTION_COURSES;
 
@@ -19,6 +19,7 @@ if (!api_is_allowed_to_edit()) {
 }
 
 $courseInfo = api_get_course_info();
+$groupId = api_get_group_id();
 $workId = isset($_GET['id']) ? intval($_GET['id']) : null;
 $workData = get_work_data_by_id($workId);
 $homework = get_work_assignment_by_id($workId);
@@ -32,8 +33,6 @@ $htmlHeadXtra[] = to_javascript_work();
 $interbreadcrumb[] = array('url' => api_get_path(WEB_CODE_PATH).'work/work.php?'.api_get_cidreq(), 'name' => get_lang('StudentPublications'));
 $interbreadcrumb[] = array('url' => '#', 'name' => get_lang('Edit'));
 
-Display::display_header();
-
 $form = new FormValidator('edit_dir', 'post', api_get_path(WEB_CODE_PATH).'work/edit_work.php?id='.$workId.'&'. api_get_cidreq());
 $form->addElement('header', get_lang('Edit'));
 
@@ -60,9 +59,7 @@ if ($homework['expires_on'] != '0000-00-00 00:00:00') {
     $there_is_a_expire_date = true;
     $defaults['enableExpiryDate'] = true;
 } else {
-    $homework['expires_on'] = api_get_local_time();
-    $expires_date_array = convert_date_to_array(api_get_local_time(), 'expires');
-    $defaults 			= array_merge($defaults, $expires_date_array);
+    $homework['expires_on'] = null;
     $there_is_a_expire_date = false;
 }
 
@@ -70,22 +67,17 @@ if ($homework['ends_on'] != '0000-00-00 00:00:00') {
     $homework['ends_on'] = api_get_local_time($homework['ends_on']);
     $there_is_a_end_date = true;
     $defaults['enableEndDate'] = true;
-
 } else {
-    $homework['ends_on'] = api_get_local_time();
-    $expires_date_array = convert_date_to_array(api_get_local_time(), 'ends');
-    $defaults 			= array_merge($defaults, $expires_date_array);
+    $homework['ends_on'] = null;
     $there_is_a_end_date = false;
 }
 
 if ($there_is_a_end_date) {
-    $end_date_array = convert_date_to_array($homework['ends_on'], 'ends');
-    $defaults = array_merge($defaults, $end_date_array);
+    $defaults['ends_on'] = $homework['ends_on'];
 }
 
 if ($there_is_a_expire_date) {
-    $expires_date_array = convert_date_to_array($homework['expires_on'], 'expires');
-    $defaults = array_merge($defaults, $expires_date_array);
+    $defaults['expires_on'] = $homework['expires_on'];
 }
 
 $defaults['add_to_calendar'] = isset($homework['add_to_calendar']) ? $homework['add_to_calendar'] : null;
@@ -93,31 +85,39 @@ $form = getFormWork($form, $defaults);
 $form->addElement('hidden', 'work_id', $workId);
 $form->addElement('style_submit_button', 'submit', get_lang('ModifyDirectory'), 'class="save"');
 
-$display_edit_form = true;
-
 if ($form->validate()) {
     $params = $form->exportValues();
     $workId = $params['work_id'];
-    $edit_check = false;
+    $editCheck = false;
     $workData = get_work_data_by_id($workId);
 
     if (!empty($workData)) {
-        $edit_check = true;
+        $editCheck = true;
     } else {
-        $edit_check = true;
+        $editCheck = true;
     }
 
-    if ($edit_check) {
+    if ($editCheck) {
         updateWork($workId, $params, $courseInfo);
-        updatePublicationAssignment($workId, $params, $courseInfo, $group_id);
+        updatePublicationAssignment($workId, $params, $courseInfo, $groupId);
         updateDirName($workData, $params['new_dir']);
 
-        Display::display_confirmation_message(get_lang('FolderEdited'));
+        $currentUrl = api_get_path(WEB_CODE_PATH).'work/edit_work.php?id='.$workId.'&'.api_get_cidreq();
+        Session::write('message', Display::return_message(get_lang('FolderEdited'), 'success'));
+        header('Location: '.$currentUrl);
+        exit;
+
     } else {
-        Display::display_warning_message(get_lang('FileExists'));
+        Session::write('message', Display::return_message(get_lang('FileExists'), 'warning'));
     }
 }
 
+Display::display_header();
+
+$message = Session::read('message');
+echo $message;
+Session::erase('message');
+
 $form->display();
 
 Display :: display_footer();

+ 33 - 0
main/work/show_file.php

@@ -0,0 +1,33 @@
+<?php
+/* For licensing terms, see /license.txt */
+
+/**
+ *	This file is responsible for  passing requested documents to the browser.
+ *	Html files are parsed to fix a few problems with URLs,
+ *	but this code will hopefully be replaced soon by an Apache URL
+ *	rewrite mechanism.
+ *
+ *	@package chamilo.work
+ */
+require_once '../inc/global.inc.php';
+require_once 'work.lib.php';
+
+$current_course_tool  = TOOL_STUDENTPUBLICATION;
+$this_section = SECTION_COURSES;
+
+// Course protection
+api_protect_course_script(true);
+
+$id = intval($_GET['id']);
+
+$course_info = api_get_course_info();
+
+if (empty($course_info)) {
+    api_not_allowed(true);
+}
+
+$result = getFile($id, $course_info, false);
+
+if ($result == false) {
+    api_not_allowed();
+}

+ 44 - 8
main/work/student_work.php

@@ -39,15 +39,25 @@ if (!empty($group_id)) {
         $show_work = true;
     } else {
         // you are not a teacher
-        $show_work = GroupManager::user_has_access($user_id, $group_id, GroupManager::GROUP_TOOL_WORK);
+        $show_work = GroupManager::user_has_access(
+            $user_id,
+            $group_id,
+            GroupManager::GROUP_TOOL_WORK
+        );
     }
 
     if (!$show_work) {
         api_not_allowed();
     }
 
-    $interbreadcrumb[] = array ('url' => '../group/group.php', 'name' => get_lang('Groups'));
-    $interbreadcrumb[] = array ('url' => '../group/group_space.php?gidReq='.$group_id, 'name' => get_lang('GroupSpace').' '.$group_properties['name']);
+    $interbreadcrumb[] = array(
+        'url' => '../group/group.php',
+        'name' => get_lang('Groups')
+    );
+    $interbreadcrumb[] = array(
+        'url' => '../group/group_space.php?gidReq='.$group_id,
+        'name' => get_lang('GroupSpace').' '.$group_properties['name']
+    );
 } else {
     if (!api_is_allowed_to_edit(false, true)) {
         api_not_allowed(true);
@@ -57,6 +67,15 @@ if (!empty($group_id)) {
 $action = isset($_GET['action']) ? $_GET['action'] : null;
 
 switch ($action) {
+    case 'export_to_pdf':
+        exportAllWork($studentId, $courseInfo, 'pdf');
+        break;
+    exit;
+    case 'download':
+        if (api_is_allowed_to_edit()) {
+            downloadAllFilesPerUser($studentId, $courseInfo);
+        }
+        break;
     case 'delete_all':
         if (api_is_allowed_to_edit()) {
             $deletedItems = deleteAllWorkPerUser($studentId, $courseInfo);
@@ -74,18 +93,33 @@ switch ($action) {
         break;
 }
 
-$interbreadcrumb[] = array ('url' => api_get_path(WEB_CODE_PATH).'work/work.php?'.api_get_cidreq(), 'name' => get_lang('StudentPublications'));
-$interbreadcrumb[] = array ('url' => '#', 'name' => $userInfo['complete_name']);
+$interbreadcrumb[] = array(
+    'url' => api_get_path(WEB_CODE_PATH).'work/work.php?'.api_get_cidreq(),
+    'name' => get_lang('StudentPublications')
+);
+$interbreadcrumb[] = array(
+    'url' => '#',
+    'name' => $userInfo['complete_name']
+);
 
 Display :: display_header(null);
 
+$workPerUser = getWorkPerUser($studentId);
+
 echo Session::read('message');
 Session::erase('message');
 
 echo '<div class="actions">';
 echo '<a href="'.api_get_path(WEB_CODE_PATH).'work/work.php?'.api_get_cidreq().'">'.
         Display::return_icon('back.png', get_lang('BackToWorksList'), '', ICON_SIZE_MEDIUM).'</a>';
+
 if (api_is_allowed_to_edit()) {
+    echo '<a href="'.api_get_path(WEB_CODE_PATH).'work/student_work.php?action=export_to_pdf&studentId='.$studentId.'&'.api_get_cidreq().'">'.
+        Display::return_icon('pdf.png', get_lang('ExportToPDF'), '', ICON_SIZE_MEDIUM).'</a>';
+
+    echo '<a href="'.api_get_path(WEB_CODE_PATH).'work/student_work.php?action=download&studentId='.$studentId.'&'.api_get_cidreq().'">'.
+        Display::return_icon('save.png', get_lang('Download'), '', ICON_SIZE_MEDIUM).'</a>';
+
     echo '<a
             onclick="javascript:if(!confirm(\''.get_lang('AreYouSureToDelete').'\')) return false;"
             href="'.api_get_path(WEB_CODE_PATH).'work/student_work.php?action=delete_all&studentId='.$studentId.'&'.api_get_cidreq().'">'.
@@ -94,13 +128,15 @@ if (api_is_allowed_to_edit()) {
 
 echo '</div>';
 
-$workPerUser = getWorkPerUser($studentId);
-
 $table = new HTML_Table(array('class' => 'data_table'));
 $column = 0;
 $row = 0;
 $headers = array(
-    get_lang('Title'), get_lang('HandedOutDate'), get_lang('HandOutDateLimit'), get_lang('Score'), get_lang('Actions')
+    get_lang('Title'),
+    get_lang('HandedOutDate'),
+    get_lang('HandOutDateLimit'),
+    get_lang('Score'),
+    get_lang('Actions')
 );
 foreach ($headers as $header) {
     $table->setHeaderContents($row, $column, $header);

+ 474 - 113
main/work/work.lib.php

@@ -223,6 +223,18 @@ function get_work_data_by_id($id)
         if (empty($work['title'])) {
             $work['title'] = basename($work['url']);
         }
+        $work['download_url'] = api_get_path(WEB_CODE_PATH).'work/download.php?id='.$work['id'].'&'.api_get_cidreq();
+        $work['view_url'] = api_get_path(WEB_CODE_PATH).'work/view.php?id='.$work['id'].'&'.api_get_cidreq();
+        $work['show_url'] = api_get_path(WEB_CODE_PATH).'work/show_file.php?id='.$work['id'].'&'.api_get_cidreq();
+        if ($work['contains_file']) {
+            $fileInfo = pathinfo($work['title']);
+            if (is_array($fileInfo) &&
+                !empty($fileInfo['extension']) &&
+                in_array($fileInfo['extension'], array('jpg', 'png', 'gif'))
+            ) {
+                $work['show_content'] = '<img src="'.$work['show_url'].'"/>';
+            }
+        }
 	}
 	return $work;
 }
@@ -376,6 +388,34 @@ function getWorkPerUser($userId)
     return $result;
 }
 
+
+function getUniqueStudentAttemptsTotal($workId, $groupId, $course_id, $sessionId)
+{
+    $work_table = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
+    $user_table = Database::get_main_table(TABLE_MAIN_USER);
+    $course_id = intval($course_id);
+    $workId = intval($workId);
+    $sessionId = intval($sessionId);
+    $groupId = intval($groupId);
+
+    $sql = "SELECT count(DISTINCT u.user_id)
+            FROM $work_table w
+            INNER JOIN $user_table u
+                ON w.user_id = u.user_id
+            WHERE
+                w.c_id = $course_id AND
+                w.session_id = $sessionId AND
+                w.parent_id = ".$workId." AND
+                w.post_group_id = ".$groupId." AND
+                w.active IN (0, 1)
+            ";
+
+    $res_document = Database::query($sql);
+    $rowCount = Database::fetch_row($res_document);
+
+    return $rowCount[0];
+}
+
 /**
  * @param mixed $workId
  * @param int $groupId
@@ -771,12 +811,12 @@ function showTeacherWorkGrid()
 {
     $columnModel = array(
         //array('name'=>'id', 'index'=>'id', 'width'=>'50', 'align'=>'left', 'hidden' => 'true'),
-        array('name'=>'type', 'index'=>'type', 'width'=>'50', 'align'=>'left', 'sortable' => 'false'),
-        array('name'=>'title', 'index'=>'title',  'width'=>'300',   'align'=>'left'),
-        array('name'=>'sent_date', 'index'=>'sent_date', 'width'=>'150',  'align'=>'left'),
-        array('name'=>'expires_on', 'index'=>'expires_on', 'width'=>'150',  'align'=>'left'),
-        array('name'=>'end_on', 'index'=>'end_on', 'width'=>'150',  'align'=>'left'),
-        array('name'=>'actions', 'index'=>'actions', 'width'=>'150', 'align'=>'left', 'sortable'=>'false')
+        array('name'=>'type', 'index'=>'type', 'width'=>'35', 'align'=>'left', 'sortable' => 'false'),
+        array('name'=>'title', 'index'=>'title',  'width'=>'300',   'align'=>'left', 'wrap_cell' => "true"),
+        array('name'=>'sent_date', 'index'=>'sent_date', 'width'=>'125',  'align'=>'left'),
+        array('name'=>'expires_on', 'index'=>'expires_on', 'width'=>'125',  'align'=>'left'),
+        array('name'=>'amount', 'index'=>'end_on', 'width'=>'110',  'align'=>'left'),
+        array('name'=>'actions', 'index'=>'actions', 'width'=>'110', 'align'=>'left', 'sortable'=>'false')
     );
     $token = null;
 
@@ -790,7 +830,7 @@ function showTeacherWorkGrid()
         get_lang('Title'),
         get_lang('SentDate'),
         get_lang('HandOutDateLimit'),
-        get_lang('HandedOut'),
+        get_lang('AmountSubmitted'),
         get_lang('Actions')
     );
 
@@ -1356,59 +1396,31 @@ function to_javascript_work()
 			    return Math.floor(d.getTime()/1000);
 			}
 
-			function validate() {
-				var expires_day = document.form1.expires_day.value;
-				var expires_month = document.form1.expires_month.value;
-				var expires_year = document.form1.expires_year.value;
-				var expires_hour = document.form1.expires_hour.value;
-				var expires_minute = document.form1.expires_minute.value;
-				var expires_date = mktime(expires_hour,expires_minute,0,expires_month,expires_day,expires_year)
-
-				var ends_day = document.form1.ends_day.value;
-				var ends_month = document.form1.ends_month.value;
-				var ends_year = document.form1.ends_year.value;
-				var ends_hour = document.form1.ends_hour.value;
-				var ends_minute = document.form1.ends_minute.value;
-				var ends_date = mktime(ends_hour,ends_minute,0,ends_month,ends_day,ends_year);
-
-				var new_dir = document.form1.new_dir.value;
-
-				msg_id1 = document.getElementById("msg_error1");
-				msg_id2 = document.getElementById("msg_error2");
-				msg_id3 = document.getElementById("msg_error3");
-				msg_id4 = document.getElementById("msg_error4");
-				msg_id5	= document.getElementById("msg_error_weight");
-
-				if (new_dir=="") {
-					msg_id1.style.display ="block";
-					msg_id1.innerHTML="'.get_lang('FieldRequired', '').'";
-					msg_id2.innerHTML="";msg_id3.innerHTML="";msg_id4.innerHTML="";msg_id5.innerHTML="";
-				} else if(document.form1.enableExpiryDate.checked && document.form1.enableEndDate.checked && expires_date > ends_date) {
-						msg_id2.style.display ="block";
-						msg_id2.innerHTML="'.get_lang('EndDateCannotBeBeforeTheExpireDate', '').'";
-						msg_id1.innerHTML="";msg_id3.innerHTML="";msg_id4.innerHTML="";msg_id5.innerHTML="";
-				} else if (!checkDate(expires_month,expires_day,expires_year)) {
-					msg_id3.style.display ="block";
-					msg_id3.innerHTML="'.get_lang('InvalidDate', '').'";
-					msg_id1.innerHTML="";msg_id2.innerHTML="";msg_id4.innerHTML="";msg_id5.innerHTML="";
-				} else if (!checkDate(ends_month,ends_day,ends_year)) {
-					msg_id4.style.display ="block";
-					msg_id4.innerHTML="'.get_lang('InvalidDate', '').'";
-					msg_id1.innerHTML="";msg_id2.innerHTML="";msg_id3.innerHTML="";msg_id5.innerHTML="";
-				} else {
-					if (document.form1.make_calification.checked) {
-					 	var weight = document.form1.weight.value;
-						 	if(weight=="") {
-								msg_id5.style.display ="block";
-								msg_id5.innerHTML="'.get_lang('WeightNecessary', '').'";
-								msg_id1.innerHTML="";msg_id2.innerHTML="";msg_id3.innerHTML="";msg_id4.innerHTML="";
-							    return false;
-                        }
-				 	}
-					document.form1.action = "work.php?'.  api_get_cidreq().'&origin='.$origin.'&gradebook='.(empty($_GET['gradebook'])?'':'view').'";
-					document.form1.submit();
-				}
-			}
+            function setFocus() {
+                $("#work_title").focus();
+            }
+
+            $(document).ready(function () {
+                setFocus();
+
+                $("#expiry_date").click(function() {
+                    var checked = $("#expiry_date").attr("checked");
+                    if (checked) {
+                        $("#option2").show();
+                        $("#option3").show();
+                        $("#end_date").attr("checked", true);
+                    } else {
+                        $("#option2").hide();
+                        $("#option3").hide();
+                        $("#end_date").attr("checked", false);
+                    }
+                });
+
+                $("#end_date").click(function() {
+                    $("#option3").toggle();
+                });
+
+            });
 			</script>';
     return $js;
 }
@@ -1542,8 +1554,8 @@ function get_count_work($work_id, $onlyMeUserId = null, $notMeUserId = null)
  */
 function getWorkListStudent($start, $limit, $column, $direction, $where_condition, $getCount = false)
 {
-    $workTable         = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
-    $workTableAssignment  = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
+    $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
+    $workTableAssignment = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
 
     $course_id          = api_get_course_int_id();
     $session_id         = api_get_session_id();
@@ -1587,7 +1599,10 @@ function getWorkListStudent($start, $limit, $column, $direction, $where_conditio
             ";
 
     $sql .= " ORDER BY $column $direction ";
-    $sql .= " LIMIT $start, $limit";
+
+    if (!empty($start) && !empty($limit)) {
+        $sql .= " LIMIT $start, $limit";
+    }
 
     $result = Database::query($sql);
 
@@ -1600,13 +1615,10 @@ function getWorkListStudent($start, $limit, $column, $direction, $where_conditio
     $url = api_get_path(WEB_CODE_PATH).'work/work_list.php?'.api_get_cidreq();
     $urlOthers = api_get_path(WEB_CODE_PATH).'work/work_list_others.php?'.api_get_cidreq().'&id=';
     while ($work = Database::fetch_array($result, 'ASSOC')) {
-
         $isSubscribed = userIsSubscribedToWork(api_get_user_id(), $work['id'], $course_id);
-
         if ($isSubscribed == false) {
             continue;
         }
-
         $work['type'] = Display::return_icon('work.png');
         $work['expires_on'] = $work['expires_on']  == '0000-00-00 00:00:00' ? null : api_get_local_time($work['expires_on']);
         if (empty($work['title'])) {
@@ -1644,9 +1656,9 @@ function getWorkListTeacher($start, $limit, $column, $direction, $where_conditio
         $direction = 'desc';
     }
 
-    $column         = !empty($column) ? Database::escape_string($column) : 'sent_date';
-    $start          = intval($start);
-    $limit          = intval($limit);
+    $column = !empty($column) ? Database::escape_string($column) : 'sent_date';
+    $start = intval($start);
+    $limit = intval($limit);
 
     // Get list from database
     if ($is_allowed_to_edit) {
@@ -1680,7 +1692,23 @@ function getWorkListTeacher($start, $limit, $column, $direction, $where_conditio
             $workId = $work['id'];
             $work['type'] = Display::return_icon('work.png');
             $work['expires_on'] = $work['expires_on']  == '0000-00-00 00:00:00' ? null : api_get_local_time($work['expires_on']);
-            $work['ends_on'] = $work['ends_on']  == '0000-00-00 00:00:00' ? null : api_get_local_time($work['ends_on']);
+            //$work['ends_on'] = $work['ends_on']  == '0000-00-00 00:00:00' ? null : api_get_local_time($work['ends_on']);
+
+            $totalUsers = getStudentSubscribedToWork(
+                $workId,
+                $course_id,
+                $group_id,
+                $session_id,
+                true
+            );
+
+            $work['amount'] = Display::label(
+                getUniqueStudentAttemptsTotal($workId, $group_id, $course_id, $session_id).'/'.
+                $totalUsers,
+                'success'
+            );
+
+            //$work['amount'] =
 
             if (empty($work['title'])) {
                 $work['title'] = basename($work['url']);
@@ -1943,16 +1971,16 @@ function get_work_user_list($start, $limit, $column, $direction, $work_id, $wher
         $direction = 'desc';
     }
 
-    $work_data          = get_work_data_by_id($work_id);
+    $work_data = get_work_data_by_id($work_id);
     $is_allowed_to_edit = api_is_allowed_to_edit(null, true);
     $condition_session  = api_get_session_condition($session_id);
     $locked = api_resource_is_locked_by_gradebook($work_id, LINK_STUDENTPUBLICATION);
 
-
     if (!empty($work_data)) {
 
         if (!empty($group_id)) {
-            $extra_conditions = " work.post_group_id = '".intval($group_id)."' "; // set to select only messages posted by the user's group
+            $extra_conditions = " work.post_group_id = '".intval($group_id)."' ";
+             // set to select only messages posted by the user's group
         } else {
             $extra_conditions = " work.post_group_id = '0' ";
         }
@@ -2005,8 +2033,11 @@ function get_work_user_list($start, $limit, $column, $direction, $work_id, $wher
         $sql = " $select
                 FROM $work_condition  $user_condition
                 WHERE $extra_conditions $where_condition $condition_session
-                ORDER BY $column $direction
-                LIMIT $start, $limit";
+                ORDER BY $column $direction";
+
+        if (!empty($start) && !empty($limit)) {
+            $sql .= "LIMIT $start, $limit";
+        }
 
         $result = Database::query($sql);
         $works = array();
@@ -2018,6 +2049,7 @@ function get_work_user_list($start, $limit, $column, $direction, $work_id, $wher
 
         while ($work = Database::fetch_array($result, 'ASSOC')) {
             $item_id = $work['id'];
+            //$workItem = get_work_data_by_id($item_id);
 
             // Get the author ID for that document from the item_property table
 			$is_author  = false;
@@ -2055,7 +2087,10 @@ function get_work_user_list($start, $limit, $column, $direction, $work_id, $wher
                 if ($work['qualification'] == '') {
                     $qualification_string = Display::label('-');
                 } else {
-                    $qualification_string = Display::label($work['qualification'], 'info');
+                    $qualification_string = Display::label(
+                        $work['qualification'].' / '.$work_data['qualification'],
+                        'info'
+                    );
                 }
             }
 
@@ -2068,8 +2103,7 @@ function get_work_user_list($start, $limit, $column, $direction, $work_id, $wher
                 $add_string = Display::label(get_lang('Expired'), 'important');
             }
 
-            if (
-                ($can_read && $work['accepted'] == '1') ||
+            if (($can_read && $work['accepted'] == '1') ||
                 ($is_author && in_array($work['accepted'], array('1', '0'))) ||
                 $is_allowed_to_edit
             ) {
@@ -2092,7 +2126,8 @@ function get_work_user_list($start, $limit, $column, $direction, $work_id, $wher
                 $link_to_download = null;
                 // If URL is present then there's a file to download keep BC.
                 if ($work['contains_file'] || !empty($work['url'])) {
-                    $link_to_download = '<a href="download.php?id='.$item_id.'">'.Display::return_icon('save.png', get_lang('Save'),array(), ICON_SIZE_SMALL).'</a> ';
+                    $link_to_download = '<a href="download.php?id='.$item_id.'&'.api_get_cidreq().'">'.
+                        Display::return_icon('save.png', get_lang('Save'),array(), ICON_SIZE_SMALL).'</a> ';
                 } else {
                    //$link_to_download = '<a href="view.php?id='.$item_id.'">'.Display::return_icon('save_na.png', get_lang('Save'),array(), ICON_SIZE_SMALL).'</a> ';
                 }
@@ -2652,15 +2687,30 @@ function getUserToWork($userId, $workId, $courseId)
 /**
  * @param int $workId
  * @param int $courseId
+ * @param bool $getCount
  * @return array
  */
-function getAllUserToWork($workId, $courseId)
+function getAllUserToWork($workId, $courseId, $getCount = false)
 {
     $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_REL_USER);
     $params = array(
         'work_id = ? and c_id = ?' => array($workId, $courseId)
     );
-    return Database::select('*', $table, array('where' => $params));
+    if ($getCount) {
+        $count = 0;
+        $result = Database::select(
+            'count(user_id) as count',
+            $table,
+            array('where' => $params),
+            'simple'
+        );
+        if (!empty($result)) {
+            $count = intval($result['count']);
+        }
+        return $count;
+    } else {
+        return Database::select('*', $table, array('where' => $params));
+    }
 }
 
 /**
@@ -2704,6 +2754,45 @@ function userIsSubscribedToWork($userId, $workId, $courseId)
     return false;
 }
 
+function getStudentSubscribedToWork($workId, $courseId, $groupId = null, $sessionId = null, $getCount = false)
+{
+    $usersInWork = null;
+    $usersInCourse = null;
+
+    if (empty($groupId)) {
+        $courseInfo = api_get_course_info_by_id($courseId);
+        $usersInCourse = CourseManager::get_user_list_from_course_code(
+            $courseInfo['code'],
+            $sessionId,
+            null,
+            null,
+            null,
+            $getCount
+        );
+    } else {
+        $usersInCourse = GroupManager::get_users(
+            $groupId,
+            false,
+            null,
+            null,
+            $getCount,
+            $courseId
+        );
+    }
+
+    if (ADD_DOCUMENT_TO_WORK == true) {
+        $usersInWork = getAllUserToWork($workId, $courseId, $getCount);
+        if (empty($usersInWork)) {
+            return $usersInCourse;
+        } else {
+            return $usersInWork;
+        }
+    } else {
+        return $usersInCourse;
+    }
+
+}
+
 /**
  * @param int $userId
  * @param int $workId
@@ -2774,12 +2863,17 @@ function getAllDocumentsFromWorkToString($workId, $courseInfo)
 }
 
 /**
- * Returns fckeditor toolbar
+ * Returns fck editor toolbar
  * @return array
  */
 function getWorkDescriptionToolbar()
 {
-    return array('ToolbarSet' => 'Work', 'Width' => '100%', 'Height' => '400');
+    return array(
+        'ToolbarStartExpanded' => 'true',
+        'ToolbarSet' => 'Work',
+        'Width' => '100%',
+        'Height' => '400'
+    );
 }
 
 /**
@@ -3390,17 +3484,14 @@ function updateWork($workId, $params, $courseInfo)
  * @param int $workId
  * @param array $params
  * @param array $courseInfo
- * @param int $group_id
+ * @param int $groupId
  */
-function updatePublicationAssignment($workId, $params, $courseInfo, $group_id)
+function updatePublicationAssignment($workId, $params, $courseInfo, $groupId)
 {
-    $workId = intval($workId);
-
     $table = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
     $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
-
+    $workId = intval($workId);
     $time = time();
-
     $course_id = $courseInfo['real_id'];
 
     // Insert into agenda
@@ -3414,7 +3505,7 @@ function updatePublicationAssignment($workId, $params, $courseInfo, $group_id)
         $date = $end_date = $time;
 
         if (!empty($params['enableExpiryDate'])) {
-            $end_date = get_date_from_select('expires', $params);
+            $end_date = $params['expires_on'];
             $date	  = $end_date;
         }
 
@@ -3431,15 +3522,15 @@ function updatePublicationAssignment($workId, $params, $courseInfo, $group_id)
         $agenda->type = 'course';
 
         if (empty($agendaId)) {
-            $agendaId = $agenda->add_event($date, $end_date, 'false', null, $title, $content, array('GROUP:'.$group_id));
+            $agendaId = $agenda->add_event($date, $end_date, 'false', null, $title, $content, array('GROUP:'.$groupId));
         } else {
             $agenda->edit_event($agendaId, $end_date, $end_date, 'false', null, $title, $content);
         }
     }
 
     $qualification = isset($params['qualification']) && !empty($params['qualification']) ? 1 : 0;
-    $expiryDate = (isset($params['enableExpiryDate']) && $params['enableExpiryDate'] == 1) ? api_get_utc_datetime(get_date_from_select('expires', $params)) : '0000-00-00 00:00:00';
-    $endDate = ((isset($params['enableEndDate']) && $params['enableEndDate']==1) ? api_get_utc_datetime(get_date_from_select('ends', $params)) : '0000-00-00 00:00:00');
+    $expiryDate = (isset($params['enableExpiryDate']) && $params['enableExpiryDate'] == 1) ? api_get_utc_datetime($params['expires_on']) : '0000-00-00 00:00:00';
+    $endDate = ((isset($params['enableEndDate']) && $params['enableEndDate']==1) ? api_get_utc_datetime($params['ends_on']) : '0000-00-00 00:00:00');
 
     $data = get_work_assignment_by_id($workId, $course_id);
 
@@ -3605,6 +3696,11 @@ function deleteWorkItem($item_id, $courseInfo)
  */
 function getFormWork($form, $defaults = array())
 {
+    if (!empty($defaults)) {
+        if (isset($defaults['submit'])) {
+            unset($defaults['submit']);
+        }
+    }
     // Create the form that asks for the directory name
     $form->addElement('text', 'new_dir', get_lang('AssignmentName'));
     $form->addRule('new_dir', get_lang('ThisFieldIsRequired'), 'required');
@@ -3618,7 +3714,8 @@ function getFormWork($form, $defaults = array())
                 get_lang('AdvancedParameters'),
                 array('style' => 'vertical-align:center')
             ).
-        ' '.get_lang('AdvancedParameters').'</span></a>'
+        ' '.get_lang('AdvancedParameters').
+        '</span></a>'
     );
 
     if (!empty($defaults) && (isset($defaults['enableEndDate']) || isset($defaults['enableExpiryDate']))) {
@@ -3658,28 +3755,29 @@ function getFormWork($form, $defaults = array())
     $form->addElement('text', 'weight', get_lang('WeightInTheGradebook'));
     $form->addElement('html', '</div>');
 
-    $form->addElement('checkbox', 'enableExpiryDate',null,get_lang('EnableExpiryDate'), 'onclick="javascript: if(this.checked){document.getElementById(\'option2\').style.display = \'block\';}else{document.getElementById(\'option2\').style.display = \'none\';}"');
-
+    $form->addElement('checkbox', 'enableExpiryDate', null, get_lang('EnableExpiryDate'), 'id="expiry_date"');
     if (isset($defaults['enableExpiryDate']) && $defaults['enableExpiryDate']) {
         $form->addElement('html', '<div id="option2" style="display: block;">');
     } else {
         $form->addElement('html', '<div id="option2" style="display: none;">');
     }
 
-    if (!isset($defaults['expires'])) {
-        $expires_date_array = convert_date_to_array(api_get_local_time(), 'expires');
-        $defaults = array_merge($defaults, $expires_date_array);
+    $currentDate = substr(api_get_local_time(), 0, 10);
+
+    if (!isset($defaults['expires_on'])) {
+        $date = substr($currentDate, 0, 10);
+        $defaults['expires_on'] = $date.' 23:59';
     }
 
-    if (!isset($defaults['ends'])) {
-        $expires_date_array = convert_date_to_array(api_get_local_time(), 'ends');
-        $defaults = array_merge($defaults, $expires_date_array);
+    if (!isset($defaults['ends_on'])) {
+        $date = substr($currentDate, 0, 10);
+        $defaults['ends_on'] = $date.' 23:59';
     }
 
-    $form->addGroup(create_group_date_select($form), 'expires', get_lang('ExpiresAt'));
+    $form->addElement('datetimepicker', 'expires_on', get_lang('ExpiresAt'));
     $form->addElement('html', '</div>');
 
-    $form->addElement('checkbox', 'enableEndDate', null, get_lang('EnableEndDate'), 'onclick="javascript: if(this.checked){document.getElementById(\'option3\').style.display = \'block\';}else{document.getElementById(\'option3\').style.display = \'none\';}"');
+    $form->addElement('checkbox', 'enableEndDate', null, get_lang('EnableEndDate'), 'id="end_date"');
 
     if (isset($defaults['enableEndDate']) && $defaults['enableEndDate']) {
        $form->addElement('html', '<div id="option3" style="display: block;">');
@@ -3687,18 +3785,16 @@ function getFormWork($form, $defaults = array())
        $form->addElement('html', '<div id="option3" style="display: none;">');
     }
 
-    $form->addGroup(create_group_date_select($form), 'ends', get_lang('EndsAt'));
+    $form->addElement('datetimepicker', 'ends_on', get_lang('EndsAt'));
     $form->addElement('html', '</div>');
 
     $form->addElement('checkbox', 'add_to_calendar', null, get_lang('AddToCalendar'));
-
-    //$form->addElement('checkbox', 'allow_text_assignment', null, get_lang('AllowTextAssignments'));
     $form->addElement('select', 'allow_text_assignment', get_lang('DocumentType'), getUploadDocumentType());
 
     $form->addElement('html', '</div>');
 
     if (isset($defaults['enableExpiryDate']) && isset($defaults['enableEndDate'])) {
-       $form->addRule(array('expires', 'ends'), get_lang('DateExpiredNotBeLessDeadLine'), 'comparedate');
+       $form->addRule(array('expires_on', 'ends_on'), get_lang('DateExpiredNotBeLessDeadLine'), 'comparedate');
     }
     if (!empty($defaults)) {
        $form->setDefaults($defaults);
@@ -3841,10 +3937,13 @@ function showStudentList($workId)
         get_lang('Works')
     );
 
+    $order = api_is_western_name_order() ? 'firstname' : 'lastname';
     $params = array(
         'autowidth' => 'true',
         'height' => 'auto',
-        'rowNum' => 10
+        'rowNum' => 10,
+        'sortname' => $order,
+        'sortorder' => 'asc'
     );
 
     $html = '<script>
@@ -3870,7 +3969,7 @@ function showStudentList($workId)
  * @param int $groupId
  * @param int $start
  * @param int $limit
- * @param $sidx
+ * @param string $sidx
  * @param string $sord
  * @param $getCount
  * @return array|int
@@ -3878,16 +3977,39 @@ function showStudentList($workId)
 function getWorkUserList($courseCode, $sessionId, $groupId, $start, $limit, $sidx, $sord, $getCount = false)
 {
     if (!empty($groupId)) {
-        $userList = GroupManager::get_users($groupId, false, $start, $limit, $getCount);
+        $userList = GroupManager::get_users($groupId, false, $start, $limit, $getCount, null, $sidx, $sord);
     } else {
         $limitString = null;
         if (!empty($start) && !empty($limit)) {
             $limitString = " LIMIT $start, $limit";
         }
+
+        $orderBy = null;
+
+        if (!empty($sidx) && !empty($sord)) {
+            $sidx = Database::escape_string($sidx);
+            $sord = Database::escape_string($sord);
+            $orderBy = "ORDER BY $sidx $sord";
+        }
+
         if (empty($sessionId)) {
-            $userList = CourseManager::get_user_list_from_course_code($courseCode, $sessionId, $limitString, null, STUDENT, $getCount);
+            $userList = CourseManager::get_user_list_from_course_code(
+                $courseCode,
+                $sessionId,
+                $limitString,
+                $orderBy ,
+                STUDENT,
+                $getCount
+            );
         } else {
-            $userList = CourseManager::get_user_list_from_course_code($courseCode, $sessionId, $limitString, null, 0, $getCount);
+            $userList = CourseManager::get_user_list_from_course_code(
+                $courseCode,
+                $sessionId,
+                $limitString,
+                $orderBy,
+                0,
+                $getCount
+            );
         }
         if ($getCount == false) {
             $userList = array_keys($userList);
@@ -3944,3 +4066,242 @@ function getWorkUserListData($workId, $courseCode, $sessionId, $groupId, $start,
     }
     return $results;
 }
+
+/**
+ * @param int $id
+ * @param array $course_info
+ * @param bool $download
+ * @return bool
+ */
+function getFile($id, $course_info, $download = true)
+{
+    $file = getFileContents($id, $course_info);
+    if (!empty($file) && is_array($file)) {
+        DocumentManager::file_send_for_download(
+            $file['path'],
+            $download,
+            $file['title']
+        );
+    }
+    return false;
+}
+
+/**
+ * @param int $id
+ * @param array $course_info
+ * @return bool
+ */
+function downloadFile($id, $course_info)
+{
+    return getFile($id, $course_info, true);
+}
+
+/**
+ * @param int $id
+ * @param array $course_info
+ * @return array|bool
+ */
+function getFileContents($id, $course_info)
+{
+    $id = intval($id);
+    if (empty($course_info) || empty($id)) {
+        return false;
+    }
+
+    $tbl_student_publication = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
+
+    if (!empty($course_info['real_id'])) {
+        $sql = 'SELECT * FROM '.$tbl_student_publication.'
+                WHERE c_id = '.$course_info['real_id'].' AND id = "'.$id.'"';
+        $result = Database::query($sql);
+        if ($result && Database::num_rows($result)) {
+            $row = Database::fetch_array($result, 'ASSOC');
+            $full_file_name = api_get_path(SYS_COURSE_PATH).api_get_course_path().'/'.$row['url'];
+
+            $item_info = api_get_item_property_info(api_get_course_int_id(), 'work', $row['id']);
+            allowOnlySubscribedUser(api_get_user_id(), $row['parent_id'], $course_info['real_id']);
+
+            if (empty($item_info)) {
+                api_not_allowed();
+            }
+
+            /*
+            field show_score in table course :
+                0 => 	New documents are visible for all users
+                1 =>    New documents are only visible for the teacher(s)
+            field visibility in table item_property :
+                0 => eye closed, invisible for all students
+                1 => eye open
+            field accepted in table c_student_publication :
+                0 => eye closed, invisible for all students
+                1 => eye open
+            ( We should have visibility == accepted, otherwise there is an
+            inconsistency in the Database)
+            field value in table c_course_setting :
+                0 => Allow learners to delete their own publications = NO
+                1 => Allow learners to delete their own publications = YES
+
+            +------------------+-------------------------+------------------------+
+            |Can download work?| doc visible for all = 0 | doc visible for all = 1|
+            +------------------+-------------------------+------------------------+
+            |  visibility = 0  | editor only             | editor only            |
+            |                  |                         |                        |
+            +------------------+-------------------------+------------------------+
+            |  visibility = 1  | editor                  | editor                 |
+            |                  | + owner of the work     | + any student          |
+            +------------------+-------------------------+------------------------+
+            (editor = teacher + admin + anybody with right api_is_allowed_to_edit)
+            */
+
+            $work_is_visible = ($item_info['visibility'] == 1 && $row['accepted'] == 1);
+            $doc_visible_for_all = ($course_info['show_score'] == 1);
+
+            $is_editor = api_is_allowed_to_edit(true, true, true);
+            $student_is_owner_of_work = user_is_author($row['id'], $row['user_id']);
+
+            if ($is_editor ||
+                ($student_is_owner_of_work) ||
+                ($doc_visible_for_all && $work_is_visible)
+            ) {
+                $title = $row['title'];
+                if (array_key_exists('filename', $row) && !empty($row['filename'])) {
+                    $title = $row['filename'];
+                }
+                $title = str_replace(' ', '_', $title);
+                event_download($title);
+                if (Security::check_abs_path(
+                    $full_file_name,
+                    api_get_path(SYS_COURSE_PATH).api_get_course_path().'/')
+                ) {
+                    return array(
+                        'path' => $full_file_name,
+                        'title' => $title
+                    );
+                }
+            }
+        }
+    }
+
+    return false;
+}
+
+/**
+ * @param int $userId
+ * @param array $courseInfo
+ * @param string $format
+ * @return bool
+ */
+function exportAllWork($userId, $courseInfo, $format = 'pdf') {
+    $userInfo = api_get_user_info($userId);
+    if (empty($userInfo) || empty($courseInfo)) {
+        return false;
+    }
+
+    $workPerUser = getWorkPerUser($userId);
+
+    switch ($format) {
+        case 'pdf':
+            if (!empty($workPerUser)) {
+                require_once api_get_path(LIBRARY_PATH).'pdf.lib.php';
+                $pdf = new PDF();
+
+                $content = null;
+                foreach ($workPerUser as $work) {
+                    $work = $work['work'];
+                    foreach ($work->user_results as $userResult) {
+                        //var_dump($userResult);exit;
+                        $content .= $userResult['title'];
+                        $content .= $userResult['sent_date'];
+                        $content .= $userResult['qualification'];
+                        $content .= $userResult['description'];
+                        //$content .= getWorkComments($userResult);
+                    }
+                }
+
+                if (!empty($content)) {
+                    $pdf->content_to_pdf(
+                        $content,
+                        null,
+                        replace_dangerous_char($userInfo['complete_name']),
+                        $courseInfo['code']
+                    );
+                }
+            }
+            break;
+    }
+}
+
+/**
+ * @param int $userId
+ * @param array $courseInfo
+ * @return bool
+ */
+function downloadAllFilesPerUser($userId, $courseInfo)
+{
+    $userInfo = api_get_user_info($userId);
+
+    if (empty($userInfo) || empty($courseInfo)) {
+        return false;
+    }
+
+    require_once api_get_path(LIBRARY_PATH).'pclzip/pclzip.lib.php';
+    $tempZipFile = api_get_path(SYS_ARCHIVE_PATH).api_get_unique_id().".zip";
+    $coursePath = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/work/';
+
+    $zip  = new PclZip($tempZipFile);
+
+    $workPerUser = getWorkPerUser($userId);
+
+    if (!empty($workPerUser)) {
+        $files = array();
+        foreach ($workPerUser as $work) {
+            $work = $work['work'];
+            foreach ($work->user_results as $userResult) {
+                if (empty($userResult['url']) || empty($userResult['contains_file'])) {
+                    continue;
+                }
+                $data = getFileContents($userResult['id'], $courseInfo);
+                if (!empty($data) && isset($data['path'])) {
+                    $files[basename($data['path'])] = array(
+                        'title' => $data['title'],
+                        'path' => $data['path']
+                    );
+                }
+            }
+        }
+
+        if (!empty($files)) {
+            Session::write('files', $files);
+            foreach ($files as $data) {
+                $zip->add(
+                    $data['path'],
+                    PCLZIP_OPT_REMOVE_PATH,
+                    $coursePath,
+                    PCLZIP_CB_PRE_ADD,
+                    'preAddAllWorkStudentCallback'
+                );
+            }
+        }
+
+        // Start download of created file
+        $name = basename(replace_dangerous_char($userInfo['complete_name'])).'.zip';
+        event_download($name.'.zip (folder)');
+        if (Security::check_abs_path($tempZipFile, api_get_path(SYS_ARCHIVE_PATH))) {
+            DocumentManager::file_send_for_download($tempZipFile, true, $name);
+            @unlink($tempZipFile);
+            exit;
+        }
+    }
+    exit;
+}
+
+
+function preAddAllWorkStudentCallback($p_event, &$p_header)
+{
+    $files = Session::read('files');
+    if (isset($files[basename($p_header['stored_filename'])])) {
+        $p_header['stored_filename'] = $files[basename($p_header['stored_filename'])]['title'];
+        return 1;
+    }
+    return 0;
+}

+ 3 - 12
main/work/work.php

@@ -35,14 +35,6 @@ $my_folder_data = get_work_data_by_id($work_id);
 $curdirpath = '';
 $htmlHeadXtra[] = api_get_jqgrid_js();
 $htmlHeadXtra[] = to_javascript_work();
-$htmlHeadXtra[] = '<script>
-function setFocus() {
-    $("#work_title").focus();
-}
-$(document).ready(function () {
-    setFocus();
-});
-</script>';
 
 $_course = api_get_course_info();
 
@@ -60,12 +52,9 @@ $submitGroupWorkUrl     = isset($_REQUEST['submitGroupWorkUrl']) ? Security::rem
 $title 			        = isset($_REQUEST['title']) ? $_REQUEST['title'] : '';
 $description 	        = isset($_REQUEST['description']) ? $_REQUEST['description'] : '';
 $uploadvisibledisabled  = isset($_REQUEST['uploadvisibledisabled']) ? Database::escape_string($_REQUEST['uploadvisibledisabled']) : $course_info['show_score'];
-
 $course_dir 		= api_get_path(SYS_COURSE_PATH).$_course['path'];
 $base_work_dir 		= $course_dir . '/work';
-
 $link_target_parameter = ""; // e.g. "target=\"_blank\"";
-
 $display_list_users_without_publication = isset($_GET['list']) && Security::remove_XSS($_GET['list']) == 'without' ? true : false;
 
 $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : 'list';
@@ -190,10 +179,12 @@ switch ($action) {
         $form = new FormValidator('form1', 'post', api_get_path(WEB_CODE_PATH).'work/work.php?action=create_dir&'. api_get_cidreq());
         $form->addElement('header', get_lang('CreateAssignment'));
         $form->addElement('hidden', 'action', 'add');
-        $form = getFormWork($form, array());
+        $defaults = isset($_POST) ? $_POST : array();
+        $form = getFormWork($form, $defaults);
         $form->addElement('style_submit_button', 'submit', get_lang('CreateDirectory'));
 
         if ($form->validate()) {
+
             $result = addDir($_POST, $user_id, $_course, $group_id, $id_session);
             if ($result) {
                 $message = Display::return_message(get_lang('DirectoryCreated'), 'success');

+ 4 - 0
main/work/work_list.php

@@ -70,6 +70,10 @@ if (api_is_allowed_to_session_edit(false, true) && !empty($workId)) {
 }
 echo '</div>';
 
+if (!empty($my_folder_data['title'])) {
+    echo Display::page_subheader($my_folder_data['title']);
+}
+
 $error_message = Session::read('error_message');
 if (!empty($error_message)) {
     echo $error_message;

+ 13 - 5
main/work/work_list_all.php

@@ -122,9 +122,17 @@ if (api_is_allowed_to_session_edit(false, true) && !empty($workId)) {
             Display::return_icon('save_pack.png', get_lang('Save'), array('style' => 'float:right;'), ICON_SIZE_MEDIUM).'</a>';
     }
     echo $display_output;
+
+
+    echo '<a href="'.api_get_path(WEB_CODE_PATH).'work/edit_work.php?'.api_get_cidreq().'&id='.$workId.'">';
+    echo Display::return_icon('edit.png', get_lang('Edit'), '', ICON_SIZE_MEDIUM).'</a>';
 }
 echo '</div>';
 
+if (!empty($my_folder_data['title'])) {
+    echo Display::page_subheader($my_folder_data['title']);
+}
+
 $error_message = Session::read('error_message');
 if (!empty($error_message)) {
     echo $error_message;
@@ -151,14 +159,14 @@ if (!empty($work_data['enable_qualification']) && !empty($check_qualification))
         get_lang('Actions')
     );
     $column_model   = array (
-        array('name'=>'type',           'index'=>'file',            'width'=>'10',   'align'=>'left', 'search' => 'false', 'sortable' => 'false'),
+        array('name'=>'type',           'index'=>'file',            'width'=>'8',   'align'=>'left', 'search' => 'false', 'sortable' => 'false'),
         array('name'=>'firstname',      'index'=>'firstname',       'width'=>'35',   'align'=>'left', 'search' => 'true'),
         array('name'=>'lastname',		'index'=>'lastname',        'width'=>'35',   'align'=>'left', 'search' => 'true'),
         array('name'=>'title',          'index'=>'title',           'width'=>'40',   'align'=>'left', 'search' => 'false', 'wrap_cell' => 'true'),
         array('name'=>'qualification',	'index'=>'qualification',	'width'=>'20',   'align'=>'left', 'search' => 'true'),
         array('name'=>'sent_date',      'index'=>'sent_date',       'width'=>'40',   'align'=>'left', 'search' => 'true', 'wrap_cell' => 'true'),
-        array('name'=>'qualificator_id','index'=>'qualificator_id', 'width'=>'30',   'align'=>'left', 'search' => 'true'),
-        array('name'=>'actions',        'index'=>'actions',         'width'=>'50',   'align'=>'left', 'search' => 'false', 'sortable'=>'false', )
+        array('name'=>'qualificator_id','index'=>'qualificator_id', 'width'=>'25',   'align'=>'left', 'search' => 'true'),
+        array('name'=>'actions',        'index'=>'actions',         'width'=>'30',   'align'=>'left', 'search' => 'false', 'sortable'=>'false', )
     );
 } else {
     $type = 'complex';
@@ -173,12 +181,12 @@ if (!empty($work_data['enable_qualification']) && !empty($check_qualification))
     );
 
     $column_model   = array (
-        array('name'=>'type',           'index'=>'file',            'width'=>'10',   'align'=>'left', 'search' => 'false', 'sortable' => 'false'),
+        array('name'=>'type',           'index'=>'file',            'width'=>'8',   'align'=>'left', 'search' => 'false', 'sortable' => 'false'),
         array('name'=>'firstname',      'index'=>'firstname',       'width'=>'35',   'align'=>'left', 'search' => 'true'),
         array('name'=>'lastname',		'index'=>'lastname',        'width'=>'35',   'align'=>'left', 'search' => 'true'),
         array('name'=>'title',          'index'=>'title',           'width'=>'40',   'align'=>'left', 'search' => 'false', 'wrap_cell' => "true"),
         array('name'=>'sent_date',      'index'=>'sent_date',      'width'=>'45',   'align'=>'left', 'search' => 'true', 'wrap_cell' => 'true'),
-        array('name'=>'actions',        'index'=>'actions',         'width'=>'50',   'align'=>'left', 'search' => 'false', 'sortable'=>'false', 'wrap_cell' => 'true')
+        array('name'=>'actions',        'index'=>'actions',         'width'=>'40',   'align'=>'left', 'search' => 'false', 'sortable'=>'false', 'wrap_cell' => 'true')
     );
 }