see #5246: notebook cleanup

skala
Laurent Opprecht 14 years ago
parent 91709cb634
commit 5c366de6c8
  1. 84
      main/notebook/access.class.php
  2. 108
      main/notebook/ajax_controller.class.php
  3. 312
      main/notebook/controller.class.php
  4. 85
      main/notebook/course_import.class.php
  5. 100
      main/notebook/csv_reader.class.php
  6. 44
      main/notebook/csv_writer.class.php
  7. 319
      main/notebook/notebook.class.php
  8. 103
      main/notebook/notebook_form.class.php
  9. 387
      main/notebook/notebook_repository.class.php
  10. 167
      main/notebook/request.class.php
  11. 40
      main/notebook/resources/js/proxy.js
  12. 104
      main/notebook/resources/js/ui.js
  13. 88
      main/notebook/upload_file_form.class.php
  14. 10
      main/template/default/notebook/edit.tpl
  15. 7
      main/template/default/notebook/header.tpl
  16. 41
      main/template/default/notebook/index.tpl
  17. 27
      main/template/default/notebook/javascript.tpl
  18. 32
      main/template/default/notebook/list.tpl
  19. 9
      main/template/default/notebook/upload.tpl

@ -0,0 +1,84 @@
<?php
namespace Notebook;
/**
* Authorize current users to perform various actions.
*
* @author Laurent Opprecht <laurent@opprecht.info> for the Univesity of Genevas
* @license /license.txt
*/
class Access extends \Access
{
/**
* Return the instance .
*
* @return \Access
*/
public static function instance()
{
static $result = null;
if (empty($result)) {
$result = new self();
}
return $result;
}
/**
* Returns true if the user has the right to edit.
*
* @return boolean
*/
public function can_edit()
{
if (Request::is_student_view()) {
return false;
}
$session_id = Request::get_session_id();
if ($session_id != 0 && api_is_allowed_to_session_edit(false, true) == false) {
return false;
}
if (!api_is_allowed_to_edit()) {
return false;
}
return true;
}
/**
* Returns true if the current user has the right to view
*
* @return boolean
*/
public function can_view()
{
$authorize = api_protect_course_script(true);
if (!$authorize) {
return false;
}
$c_id = Request::get_c_id();
if (empty($c_id)) {
return false;
}
return true;
}
public function authorize()
{
if (!$this->can_view()) {
return false;
}
$c_id = Request::get_c_id();
if (empty($c_id)) {
return false;
}
return true;
}
}

@ -0,0 +1,108 @@
<?php
namespace Notebook;
use \Display;
use \Template;
use \FormValidator;
use \Security;
use \Uri;
use Header;
/**
* Ajax controller. Dispatch request and perform required action.
*
* - delete one note
* - delete all notes in a course/session
* - returns a note from its id
*
* Usage:
*
* $controller = AjaxController::instance();
* $controller->run();
*
* @author Laurent Opprecht <laurent@opprecht.info> for the Univesity of Genevas
* @license /license.txt
*/
class AjaxController extends \AjaxController
{
const ACTION_REMOVE = 'remove';
const ACTION_REMOVE_BY_COURSE = 'remove_by_course';
const ACTION_FIND_BY_ID = 'find_by_id';
/**
* Return the instance of the controller.
*
* @return \Notebook\AjaxController
*/
public static function instance()
{
static $result = null;
if (empty($result)) {
$result = new self(Access::instance());
}
return $result;
}
/**
* Prepare the environment. Set up breadcrumps and raise tracking event.
*/
protected function prolog()
{
event_access_tool(TOOL_NOTEBOOK);
}
public function is_allowed_to_edit()
{
return $this->access()->can_edit();
}
/**
* Remove/delete a Notebook entry
*/
public function remove()
{
if (!$this->is_allowed_to_edit()) {
$this->forbidden();
return;
}
$item = Request::get_item_key();
$success = Notebook::repository()->remove($item);
$message = $success ? '' : get_lang('Error');
$this->response($success, $message);
}
/**
* Remove/delete all notebook entries belonging to a course.
*/
public function remove_by_course()
{
if (!$this->is_allowed_to_edit()) {
$this->forbidden();
return;
}
$course = Request::get_course_key();
$success = Notebook::repository()->remove_by_course($course);
$message = $success ? '' : get_lang('Error');
$this->response($success, $message);
}
public function find_by_id()
{
$c_id = Request::get_c_id();
$id = Request::get_id();
$item = Notebook::repository()->find_one_by_id($c_id, $id);
$data = (object) array();
if ($item) {
$data->title = $item->title;
$data->description = $item->description;
}
$this->response($success, '', $data);
}
}

@ -0,0 +1,312 @@
<?php
namespace Notebook;
use \ChamiloSession as Session;
use \Display;
use \Template;
use \FormValidator;
use \Security;
use Uri;
use Redirect;
use Chamilo;
use Javascript;
/**
* Controller for notebook. Dispatch request and peform required action.
*
* - list notes for course
* - add/edit notes entry
* - change view from table to details
*
* Usage:
*
* $controller = Controller::instance();
* $controller->run();
*
* @package chamilo.course_description
* @author Christian Fasanando <christian1827@gmail.com>
* @author Laurent Opprecht <laurent@opprecht.info> for the Univesity of Genevas
* @license see /license.txt
*/
class Controller extends \Controller
{
const ACTION_ADD = 'add';
const ACTION_EDIT = 'edit';
const ACTION_DELETE = 'delete';
const ACTION_INDEX = 'index';
const ACTION_DEFAULT = 'index';
const ACTION_EXPORT_CSV = 'export_csv';
const ACTION_IMPORT_CSV = 'import_csv';
/**
* Return the instance of the controller.
*
* @return \Noteboook\Controller
*/
public static function instance()
{
static $result = null;
if (empty($result)) {
$result = new self(Access::instance());
}
return $result;
}
/**
* Action to perform.
* Returns the request parameter.
*
* @return string
*/
public function get_action()
{
if (Request::is_student_view()) {
return self::ACTION_INDEX;
}
$result = parent::get_action();
$result = $result ? $result : self::ACTION_DEFAULT;
return $result;
}
public function is_allowed_to_edit()
{
return $this->access()->can_edit();
}
/**
* Prepare the environment. Set up breadcrumps and raise tracking event.
*/
protected function prolog()
{
global $interbreadcrumb;
$interbreadcrumb = array();
$interbreadcrumb[] = array('url' => 'index.php', 'name' => get_lang('Notebook'));
global $this_section;
$this_section = SECTION_COURSES;
global $current_course_tool;
$current_course_tool = TOOL_NOTEBOOK;
// Tracking
event_access_tool(TOOL_NOTEBOOK);
}
/**
* Returns a url for an action that the controller can process
*
* @param string $action
* @param array $params
* @return string
*/
public function url($action = '', $params = array())
{
$url_params = Uri::course_params();
if ($c_id = Request::get_c_id()) {
$url_params[Request::PARAM_C_ID] = $c_id;
}
if ($id = Request::get_id()) {
$url_params[Request::PARAM_ID] = $id;
}
if ($session_id = Request::get_session_id()) {
$url_params[Request::PARAM_SESSION_ID] = $session_id;
}
if ($action) {
$url_params[Request::PARAM_ACTION] = $action;
}
foreach ($params as $key => $value) {
$url_params[$key] = $value;
}
$result = Uri::url('/main/notebook/index.php', $url_params, false);
return $result;
}
/**
* List course descriptions.
*
* @param array messages
*/
public function index()
{
$course = Request::get_course_key();
$user_id = api_get_user_id();
$column = Request::get_sort_column();
$direction = Request::get_sort_direction();
$order_by = $column ? "$column $direction" : '';
$repo = Notebook::repository();
$items = $repo->find_by_course_and_user($course, $user_id, $order_by);
$data = (object) array();
$data->items = $items;
$data->sort = $sort;
$data->sort_direction = $direction;
$data->sort_column = $column;
$this->render('index', $data);
}
/**
* Performs the edit action.
*/
public function edit()
{
if (!$this->is_allowed_to_edit()) {
$this->forbidden();
return;
}
$id = Request::get_id();
$c_id = Request::get_c_id();
$repo = Notebook::repository();
$item = $repo->find_one_by_id($c_id, $id);
$action = $this->url(self::ACTION_EDIT);
$form = NotebookForm::create($action, $item);
if ($form->validate()) {
$success = $repo->save($item);
$message = $success ? get_lang('NotebookUpdated') : get_lang('Error');
$home = $this->url(self::ACTION_DEFAULT);
Redirect::go($home);
}
$data = (object) array();
$data->form = $form;
$this->render('edit', $data);
}
/**
* Perform the add action
*/
public function add()
{
if (!$this->is_allowed_to_edit()) {
$this->forbidden();
return;
}
$c_id = Request::get_c_id();
$session_id = Request::get_session_id();
$item = Notebook::create();
$item->c_id = $c_id;
$item->session_id = $session_id;
$action = $this->url(self::ACTION_ADD);
$form = NotebookForm::create($action, $item);
if ($form->validate()) {
$repo = Notebook::repository();
$success = $repo->save($item);
$message = $success ? get_lang('NotebookAdded') : get_lang('Error');
$home = $this->url();
Redirect::go($home);
}
$data = (object) array();
$data->type = $type;
$data->form = $form;
$this->render('edit', $data);
}
/**
* Performs the delete action.
*
* @see AjaxController
*/
public function delete()
{
if (!$this->is_allowed_to_edit()) {
$this->forbidden();
return;
}
$this->missing();
}
public function export_csv()
{
$course = Request::get_course_key();
$items = Notebook::repository()->find_by_course($course);
$writer = CsvWriter::create();
$writer->add($items);
$path = $writer->get_path();
\DocumentManager :: file_send_for_download($path, true, get_lang('Notebook') . '.csv');
}
public function import_csv()
{
if (!$this->is_allowed_to_edit()) {
$this->forbidden();
return;
}
$action = $this->url(self::ACTION_IMPORT_CSV);
$form = UploadFileForm::create($action);
$form->init();
if ($form->validate()) {
// $delete_all = $form->get_delete_all();
// if ($delete_all) {
// $course = Request::get_course_key();
// $repo = Notebook::repository();
// $repo->remove_by_course($course);
// }
$file = $form->get_file();
$path = $file->tmp_name;
$reader = new CsvReader($path);
$items = $reader->get_items();
$course = Request::get_course_key();
$import = new CourseImport($course);
$import->add($items);
$home = $this->url(self::ACTION_DEFAULT);
Redirect::go($home);
}
$data = (object) array();
$data->form = $form;
$this->render('upload', $data);
}
/**
* Render a template using data. Adds a few common parameters to the data array.
*
* @see /main/template/default/course_description/
* @param string $template
* @param array $data
*/
protected function render($template, $data)
{
$data = $data ? $data : (object) array();
$_user = api_get_user_info();
$session_id = Request::get_session_id();
$data->session_image = api_get_session_image($session_id, $_user);
$data->sec_token = $this->access()->get_token();
$data->root = $this->url('');
$data->session_id = $session_id;
$data->c_id = Request::get_c_id();
$data->is_allowed_to_edit = $this->is_allowed_to_edit();
parent::render("notebook/$template.tpl", $data);
}
}

@ -0,0 +1,85 @@
<?php
namespace Notebook;
/**
* Import notebook entries into a course/session.
*
* Usage
*
* //init
* $course = (object)array();
* $course->c_id = xxx;
* $course->session_id = xxx;
* $import = new CourseImport($course);
*
* //create notebook entry
* $item = (object)array();
* $item->title = 'xxx';
* $item->description = 'xxx';
*
* //import notebook entry
* $import->add($item);
*
* @license /licence.txt
* @author Laurent Opprecht <laurent@opprecht.info>
*/
class CourseImport
{
protected $course = false;
protected $update_existing_entries = false;
protected $objects_imported = 0;
protected $objects_skipped = 0;
public function __construct($course)
{
$this->course = $course;
}
public function get_course()
{
return $this->course;
}
public function get_objects_imported()
{
return $this->objects_imported;
}
public function get_objects_skipped()
{
return $this->objects_skipped;
}
/**
*
* @param array $items
*/
public function add($items)
{
$this->objects_imported = 0;
$this->objects_skipped = 0;
foreach ($items as $item) {
$title = $item->title;
$description = $item->description;
if (empty($title) || empty($description)) {
$this->objects_skipped++;
continue;
}
$item->c_id = $this->course->c_id;
$item->session_id = $this->course->session_id;
$repo = Notebook::repository();
$success = $repo->save($item);
if ($success) {
$this->objects_imported++;
} else {
$this->objects_skipped++;
}
}
}
}

@ -0,0 +1,100 @@
<?php
namespace Notebook;
/**
* Read a csv file and returns notebook entries contained in the file.
*
* @license /licence.txt
* @author Laurent Opprecht <laurent@opprecht.info>
*/
class CsvReader implements \Iterator
{
protected $path;
protected $items = null;
protected $index = 0;
public function __construct($path)
{
$this->path = $path;
}
public function get_path()
{
return $this->path;
}
public function get_items()
{
if (is_null($this->items)) {
$this->items = $this->read();
}
return $this->items;
}
/**
* Read file and returns an array filled up with its' content.
*
* @return array of objects
*/
protected function read()
{
$result = array();
$path = $this->path;
if (!is_readable($path)) {
return array();
}
$items = \Import::csv_reader($path);
foreach ($items as $item) {
$item = (object) $item;
$title = isset($item->title) ? trim($item->title) : '';
$description = isset($item->description) ? trim($item->description) : '';
$name = \Security::remove_XSS($name);
$description = \Security::remove_XSS($description);
$is_blank_line = empty($name) && empty($description);
if ($is_blank_line) {
continue;
}
$item = new Notebook();
$item->title = $title;
$item->description = $description;
$result[] = $item;
}
return $result;
}
public function current()
{
$items = $this->get_items();
return isset($items[$this->index]) ? $items[$this->index] : null;
}
public function key()
{
return $this->index;
}
public function next()
{
$this->index++;
}
public function rewind()
{
$this->index = 0;
}
public function valid()
{
$items = $this->get_items();
return count($items) > $this->index;
}
}

@ -0,0 +1,44 @@
<?php
namespace Notebook;
use Chamilo;
/**
* Write notebook entries to a file in CSV format.
*
* @license /licence.txt
* @author Laurent Opprecht <laurent@opprecht.info>
*/
class CsvWriter extends \CsvObjectWriter
{
/**
*
* @return \Notebook\CsvWriter
*/
public static function create($path = '', $delimiter = ';', $enclosure = '"')
{
return new self($path, $delimiter, $enclosure);
}
protected $path = '';
function __construct($path = '', $delimiter = ';', $enclosure = '"')
{
$path = $path ? $path : Chamilo::temp_file();
$this->path = $path;
$stream = new \FileWriter($path);
$map = array(
'title' => 'title',
'description' => 'description'
);
parent::__construct($stream, $map, $delimiter, $enclosure);
}
function get_path()
{
return $this->path;
}
}

@ -0,0 +1,319 @@
<?php
namespace Notebook;
/**
*
* @license see /license.txt
* @author autogenerated
*/
class Notebook extends \Entity
{
/**
* @return \Notebook\NotebookRepository
*/
public static function repository(){
return NotebookRepository::instance();
}
/**
* @return \Notebook\Notebook
*/
public static function create($data = null){
return new self($data);
}
/**
* @var integer $c_id
*/
protected $c_id;
/**
* @var integer $notebook_id
*/
protected $notebook_id;
/**
* @var integer $user_id
*/
protected $user_id;
/**
* @var string $course
*/
protected $course;
/**
* @var integer $session_id
*/
protected $session_id;
/**
* @var string $title
*/
protected $title;
/**
* @var text $description
*/
protected $description;
/**
* @var datetime $creation_date
*/
protected $creation_date;
/**
* @var datetime $update_date
*/
protected $update_date;
/**
* @var integer $status
*/
protected $status;
/**
* Set c_id
*
* @param integer $value
* @return Notebook
*/
public function set_c_id($value)
{
$this->c_id = $value;
return $this;
}
/**
* Get c_id
*
* @return integer
*/
public function get_c_id()
{
return $this->c_id;
}
/**
* Alias for notebook id. Better to use the same naming convention
* for all classes.
*
* @return integer
*/
public function get_id()
{
return $this->notebook_id;
}
/**
* Set notebook_id
*
* @param integer $value
* @return Notebook
*/
public function set_id($value)
{
$this->notebook_id = $value;
return $this;
}
/**
* Set notebook_id
*
* @param integer $value
* @return Notebook
*/
public function set_notebook_id($value)
{
$this->notebook_id = $value;
return $this;
}
/**
* Get notebook_id
*
* @return integer
*/
public function get_notebook_id()
{
return $this->notebook_id;
}
/**
* Set user_id
*
* @param integer $value
* @return Notebook
*/
public function set_user_id($value)
{
$this->user_id = $value;
return $this;
}
/**
* Get user_id
*
* @return integer
*/
public function get_user_id()
{
return $this->user_id;
}
/**
* Set course
*
* @param string $value
* @return Notebook
*/
public function set_course($value)
{
$this->course = $value;
return $this;
}
/**
* Get course
*
* @return string
*/
public function get_course()
{
return $this->course;
}
/**
* Set session_id
*
* @param integer $value
* @return Notebook
*/
public function set_session_id($value)
{
$this->session_id = $value;
return $this;
}
/**
* Get session_id
*
* @return integer
*/
public function get_session_id()
{
return $this->session_id;
}
/**
* Set title
*
* @param string $value
* @return Notebook
*/
public function set_title($value)
{
$this->title = $value;
return $this;
}
/**
* Get title
*
* @return string
*/
public function get_title()
{
return $this->title;
}
/**
* Set description
*
* @param text $value
* @return Notebook
*/
public function set_description($value)
{
$this->description = $value;
return $this;
}
/**
* Get description
*
* @return text
*/
public function get_description()
{
return $this->description;
}
/**
* Set creation_date
*
* @param datetime $value
* @return Notebook
*/
public function set_creation_date($value)
{
$this->creation_date = $value;
return $this;
}
/**
* Get creation_date
*
* @return datetime
*/
public function get_creation_date()
{
return $this->creation_date;
}
/**
* Set update_date
*
* @param datetime $value
* @return Notebook
*/
public function set_update_date($value)
{
$this->update_date = $value;
return $this;
}
/**
* Get update_date
*
* @return datetime
*/
public function get_update_date()
{
return $this->update_date;
}
/**
* Set status
*
* @param integer $value
* @return Notebook
*/
public function set_status($value)
{
$this->status = $value;
return $this;
}
/**
* Get status
*
* @return integer
*/
public function get_status()
{
return $this->status;
}
}

@ -0,0 +1,103 @@
<?php
namespace Notebook;
use Chamilo;
/**
* Form to edit/Create notebook entries.
*
* @license /licence.txt
* @author Laurent Opprecht <laurent@opprecht.info>
*/
class NotebookForm extends \FormValidator
{
/**
*
* @param string $action
* @param \Notebook\Notebook $item
* @return \Notebook\NotebookForm
*/
static function create($action, $item = null)
{
$result = new self('notebook', 'post', $action);
if ($item) {
$result->init($item);
}
return $result;
}
protected $notebook;
function __construct($form_name = 'notebook', $method = 'post', $action = '', $target = '', $attributes = null, $track_submit = true)
{
parent::__construct($form_name, $method, $action, $target, $attributes, $track_submit);
}
/**
*
* @return \Notebook\Notebook
*/
public function get_notebook()
{
return $this->notebook;
}
public function set_notebook($value)
{
$this->notebook = $value;
}
/**
*
* @param \Notebook\Notebook $notebook
*/
function init($notebook = null)
{
$this->set_notebook($notebook);
$defaults = array();
$defaults['title'] = $notebook->title;
$defaults['description'] = $notebook->description;
$this->add_hidden('c_id', $notebook->c_id);
$this->add_hidden('id', $notebook->id);
$this->add_hidden('session_id', $notebook->session_id);
$this->add_hidden(Request::PARAM_SEC_TOKEN, Access::instance()->get_token());
$form_name = $notebook->id ? get_lang('ModifyNote') : get_lang('NoteAddNew');
$this->add_header($form_name);
$this->add_textfield('title', get_lang('NoteTitle'), $required = true, array('class' => 'span3'));
if (api_is_allowed_to_edit()) {
$toolbar = array('ToolbarSet' => 'Notebook', 'Width' => '100%', 'Height' => '300');
} else {
$toolbar = array('ToolbarSet' => 'NotebookStudent', 'Width' => '100%', 'Height' => '300', 'UserStatus' => 'student');
}
$this->add_html_editor('description', get_lang('NoteComment'), true, api_is_allowed_to_edit(), $toolbar);
$this->add_button('save', get_lang('Save'), array('class' => 'btn save'));
$this->setDefaults($defaults);
}
function update_model()
{
$values = $this->exportValues();
$notebook = $this->get_notebook();
$notebook->title = $values['title'];
$notebook->description = $values['description'];
}
function validate()
{
$result = parent::validate();
if ($result) {
$this->update_model();
}
return $result;
}
}

@ -0,0 +1,387 @@
<?php
namespace Notebook;
use Database;
/**
* Notebook repository. Interface with the database.
*
* @author Laurent Opprecht <laurent@opprecht.info> for the University of Geneva
* @licence /license.txt
*/
class NotebookRepository
{
/**
* Return the instance of the repository.
*
* @return \Notebook\NotebookRepository
*/
public static function instance()
{
static $result = null;
if (empty($result)) {
$result = new self();
}
return $result;
}
/**
*
* @return string
*/
public function get_table()
{
return Database :: get_course_table(TABLE_NOTEBOOK);
}
/**
*
* @return string
*/
public function get_tool()
{
return TOOL_NOTEBOOK;
}
/**
*
*
* @param string $where Where filter to apply
* @return array
*/
public function find($where, $orderby = '', $limit = null)
{
$table_item_property = Database::get_course_table(TABLE_ITEM_PROPERTY);
$table = $this->get_table();
$tool = $this->get_tool();
$sql = "SELECT n.*,
prop.id AS property_id,
prop.tool,
prop.insert_user_id,
prop.insert_date,
prop.lastedit_date,
prop.ref,
prop.lastedit_type,
prop.lastedit_user_id,
prop.to_group_id,
prop.to_user_id,
prop.visibility,
prop.start_visible,
prop.end_visible,
prop.id_session
FROM
$table AS n,
$table_item_property AS prop
WHERE
(n.notebook_id = prop.ref AND
n.c_id = prop.c_id AND
prop.tool = '$tool')";
$sql .= $where ? "AND ($where)" : '';
$sql .= ' ORDER BY ';
$sql .= $orderby ? $orderby : 'creation_date ASC';
if ($limit) {
$from = (int) $limit->from;
$count = (int) $limit->count;
$sql .= " LIMIT $from, $count";
}
$rs = Database :: query($sql);
while ($data = Database::fetch_object($rs)) {
$result[] = Notebook::create($data);
}
return $result;
}
public function count($where)
{
$table_item_property = Database::get_course_table(TABLE_ITEM_PROPERTY);
$table = $this->get_table();
$tool = $this->get_tool();
$sql = "SELECT count(*) AS val
FROM
$table AS n,
$table_item_property AS prop
WHERE
(n.notebook_id = prop.ref AND
n.c_id = prop.c_id AND
prop.tool = '$tool')";
$sql .= $where ? "AND ($where)" : '';
$sql .= " ORDER BY name ASC";
$rs = Database :: query($sql);
while ($data = Database::fetch_object($rs)) {
return $data->val;
}
return 0;
}
/**
*
* @param string $where
* @return \Notebook\notebook_id
*/
public function find_one($where)
{
$items = $this->find($where);
foreach ($items as $item) {
return $item;
}
return null;
}
/**
* Retrieve one course description from its ids.
*
* @param int|Course $c_id
* @param int $id
* @return \notebook_id\notebook_id
*/
public function find_one_by_id($c_id, $id)
{
$c_id = is_object($c_id) ? $c_id->get_id() : (int) $c_id;
return $this->find_one("n.c_id = $c_id AND n.notebook_id = $id");
}
/**
* Retrieve one course description from its ids.
*
* @param int|Course $c_id
* @param string name
* @return \Notebook\Notebook
*/
public function find_one_by_course_and_title($c_id, $title)
{
$c_id = is_object($c_id) ? $c_id->get_id() : (int) $c_id;
$name = Database::escape_string($name);
return $this->find_one("n.c_id = $c_id AND n.title = '$title'");
}
/**
* Returns the list of notes belonging to a specific course and
* session.
*
* @param object $course
* @return Array
*/
public function find_by_course($course, $orderby = '', $limit = null)
{
$c_id = (int) $course->c_id;
$session_id = isset($course->session_id) ? (int) $course->session_id : 0;
if (empty($c_id)) {
return array();
}
$condition_session = api_get_session_condition($session_id);
$where = "n.c_id = $c_id $condition_session";
return $this->find($where, $orderby, $limit);
}
/**
* Returns the list of notes belonging to a specific course and
* session.
*
* @param object $course
* @return Array
*/
public function find_by_course_and_user($course, $user, $orderby = '', $limit = null)
{
$user_id = is_object($user) ? (int)$user->user_id : (int)$user;
$c_id = (int) $course->c_id;
$session_id = isset($course->session_id) ? (int) $course->session_id : 0;
if (empty($c_id)) {
return array();
}
$condition_session = api_get_session_condition($session_id);
$where = "user_id = $user_id AND n.c_id = $c_id $condition_session";
return $this->find($where, $orderby, $limit);
}
public function count_by_course($course)
{
$c_id = (int) $course->c_id;
$session_id = isset($course->session_id) ? (int) $course->session_id : 0;
if (empty($c_id)) {
return 0;
}
$condition_session = api_get_session_condition($session_id);
$where = "n.c_id = $c_id $condition_session";
return $this->count($where);
}
/**
*
* @param object \Notebook\Notebook
* @return bool
*/
public function save($item)
{
$id = $item->id;
if (empty($id)) {
return $this->insert($item);
} else {
return $this->update($item);
}
}
/**
*
* @param \Notebook\Notebook $item
* @return bool
*/
public function insert($item)
{
$c_id = (int) $item->c_id;
$user_id = (int)$item->user_id;
$user_id = $user_id ? $user_id : api_get_user_id();
$_course = api_get_course_info_by_id($c_id);
$course = $_course['code'];
$session_id = (int) $item->session_id;
$session_id = $session_id ? $session_id : api_get_session_id();
$title = trim($item->title);
$title = Database::escape_string($title);
$description = trim($item->description);
$description = Database::escape_string($description);
$now = time();
$creation_date = date('Y-m-d H:i:s', $now);
$update_date = $creation_date;
$status = (int)$item->status;
$status = $status ? $status : '0';
$table = $this->get_table();
$sql = "INSERT INTO $table
(c_id, user_id, course, session_id, title, description, creation_date, update_date, status)
VALUES
($c_id, $user_id, '$course', $session_id, '$title', '$description', '$creation_date', '$update_date', $status)";
$result = (bool) Database :: query($sql);
if ($result) {
$id = Database::insert_id();
$item->id = $id;
$item->creation_date = $creation_date;
$item->update_date = $update_date;
$item->status = (int)$status;
$item->course = $course;
$item->session_id = $session_id;
$item->user_id = $user_id;
//$_course = api_get_course_info_by_id($c_id);
$tool = $this->get_tool();
//$user_id = api_get_user_id();
api_item_property_update($_course, $tool, $id, 'NotebookAdded', $user_id);
}
return $result;
}
/**
*
* @param \Notebook\Notebook $item
* @return bool
*/
function update($item)
{
$c_id = (int) $item->c_id;
$id = (int) $item->id;
$user_id = (int)$item->user_id;
$user_id = $user_id ? $user_id : api_get_user_id();
$title = trim($item->title);
$title = Database::escape_string($title);
$description = trim($item->description);
$description = Database::escape_string($description);
$session_id = (int) $item->session_id;
$session_id = $session_id ? $session_id : '0';
$creation_date = $item->creation_date;
$creation_date = is_string($creation_date) ? strtotime($creation_date) : $creation_date;
$creation_date = date('Y-m-d H:i:s', $creation_date);
$now = time();
$creation_date = date('Y-m-d H:i:s', $now);
$update_date = $creation_date;
$status = (int)$item->status;
$status = $status ? $status : '0';
$table = $this->get_table();
$sql = "UPDATE $table SET
user_id = $user_id,
session_id = $session_id,
title = '$title',
description = '$description',
update_date = '$update_date',
status = $status
WHERE
c_id = $c_id AND
notebook_id = $id";
$result = (bool) Database :: query($sql);
if ($result) {
$item->update_date = $update_date;
$_course = api_get_course_info_by_id($c_id);
$tool = $this->get_tool();
//$user_id = api_get_user_id();
api_item_property_update($_course, $tool, $id, 'NotebookUpdated', $user_id);
}
return $result;
}
/**
*
* @param object $item
* @return boolean
*/
public function remove($item)
{
$table = $this->get_table();
$c_id = (int) $item->c_id;
$id = (int) $item->id;
if (empty($c_id) || empty($id)) {
return false;
}
$sql = "DELETE FROM $table WHERE c_id=$c_id AND notebook_id=$id";
$result = Database :: query($sql);
if ($result) {
$tool = $this->get_tool();
$tbl_property = Database :: get_course_table(TABLE_ITEM_PROPERTY);
$sql = "DELETE FROM $tbl_property WHERE c_id=$c_id AND ref=$id AND tool='$tool'";
Database :: query($sql);
}
return (bool) $result;
}
/**
*
* @param object $course
* @return int
*/
public function remove_by_course($course)
{
$items = $this->find_by_course($course);
foreach ($items as $item) {
$success = $this->remove($item);
if ($success) {
$result++;
}
}
return $result;
}
}

@ -0,0 +1,167 @@
<?php
namespace Notebook;
use \ChamiloSession as Session;
/**
* Html request for course description.
*
* @author Laurent Opprecht <laurent@opprecht.info> for the Univesity of Genevas
* @license /license.txt
*/
class Request extends \Request
{
const PARAM_ID = 'id';
const PARAM_IDS = 'ids';
const PARAM_C_ID = 'c_id';
const PARAM_SESSION_ID = 'id_session';
const PARAM_ACTION = 'action';
const PARAM_SEC_TOKEN = 'sec_token';
const PARAM_IS_STUDENT_VIEW = 'isStudentView';
const PARAM_SORT_COLUMN = 'sort_column';
const PARAM_SORT_DIRECTION = 'sort_direction';
/**
* Action to perform. *
* @return string
*/
public static function get_action()
{
$result = Request::get(self::PARAM_ACTION, '');
return $result;
}
/**
* Returns the object id.
*
* @return int
*/
public static function get_id()
{
$result = \Request::get(self::PARAM_ID, 0);
$result = intval($result);
return $result;
}
/**
* List of objet ids
*
* @return array
*/
public static function get_ids()
{
$result = Request::get(self::PARAM_IDS, array());
if (is_array($result)) {
return $result;
}
$result = trim($result);
if (empty($result)) {
return array();
}
$result = explode(',', $result);
return $result;
}
/**
* Returns the course id.
*
* @return int
*/
public static function get_c_id()
{
$result = Request::get(self::PARAM_C_ID, 0);
$result = intval($result);
$result = $result ? $result : api_get_real_course_id();
$result = $result ? $result : 0;
return $result;
}
/**
* Returns the session id.
*
* @return int
*/
public static function get_session_id()
{
$result = Request::get(self::PARAM_SESSION_ID, 0);
$result = intval($result);
return $result;
}
/**
* Returns the security token.
*
* @return string
*/
public static function get_security_token()
{
$result = Request::get(self::PARAM_SEC_TOKEN, 0);
return $result;
}
/**
* Returns true if the user is in "student view". False otherwise.
*
* @return bool
*/
public static function is_student_view()
{
return Request::get(self::PARAM_IS_STUDENT_VIEW, false) == 'true';
}
/**
* Returns a course key parameters. I.e. not a real course but an
* object with the course c_id and session set up.
*
* @return object
*/
public static function get_course_key()
{
$result = (object) array();
$result->c_id = Request::get_c_id();
$result->session_id = Request::get_session_id();
return $result;
}
/**
* Returns an item key. I.e. not a real entity object but an
* object with the object keys set up.
*
* @return object
*/
public static function get_item_key()
{
$result = (object) array();
$result->c_id = Request::get_c_id();
$result->id = Request::get_id();
return $result;
}
public static function get_sort_column()
{
$result = Request::get(self::PARAM_SORT_COLUMN, 'name');
if($result == 'title'){
return $result;
}
if($result == 'creation_date'){
return $result;
}
if($result == 'update_date'){
return $result;
}
return 'creation_date';
}
public static function get_sort_direction(){
$result = Request::get(self::PARAM_SORT_DIRECTION, 'name');
$result = strtoupper($result);
$result = ($result == 'DESC') ? 'DESC' : 'ASC';
return $result;
}
}

@ -0,0 +1,40 @@
/**
* Define a client proxy for ajax calls.
*/
function Proxy() {};
Proxy.prototype.root = function(){
return context.ajax;
}
Proxy.prototype.post = function(data, f){
if(typeof(context)!=='undefined' && typeof(context.sec_token)!=='undefined'){
data.sec_token = context.sec_token;
}
$.post(this.root(), data, f, 'json');
}
var notebook = new Proxy();
notebook.remove = function(c_id, id, f)
{
var data = {
c_id: c_id,
id: id,
action: 'remove'
};
this.post(data, f);
};
notebook.remove_by_course = function(c_id, session_id, f)
{
var data = {
c_id: c_id,
session_id: session_id,
action: 'remove_by_course'
};
this.post(data, f);
};

@ -0,0 +1,104 @@
/**
* User interface objects.
*/
var message = {};
message.update = function(data){
var text = typeof(data)=='string' ? data : data.message;
$('#messages').html(text);
}
message.error = function(data){
text = typeof(data)=='string' ? data : data.message;
if(! text){
return;
}
$('#messages').html('<div class="error-message">' + text + '</div>');
}
message.info = function(data){
text = typeof(data)=='string' ? data : data.message;
if(! text){
return;
}
$('#messages').html('<div class="normal-message">' + text + '</div>');
}
message.confirmation = function(data){
text = typeof(data)=='string' ? data : data.message;
if(! text){
return;
}
$('#messages').html('<div class="confirmation-message">' + text + '</div>');
}
message.warning = function(data){
text = typeof(data)=='string' ? data : data.message;
if(! text){
return;
}
$('#messages').html('<div class="warning-message">' + text + '</div>');
}
var ui = {};
ui.message = message;
ui.loading = function(btn){
$(btn).addClass("loading");
};
ui.done = function(btn){
$(btn).removeClass("loading");
};
ui.confirm = function(){
if(!window.confirm(lang.ConfirmYourChoice)){
return false;
} else {
return true;
}
};
ui.remove = function(name, btn){
if(!this.confirm()){
return false;
}
var item = $('#'+name);
var id = item.attr('data-id');
var c_id = item.attr('data-c_id');
var f = function(data){
if(data.success){
item.remove();
}
message.update(data);
ui.done(btn);
};
ui.loading(btn);
ui.proxy.remove(c_id, id, f);
};
ui.remove_by_course = function(name, btn){
if(!this.confirm()){
return false;
}
var item = $('#'+name);
var c_id = item.attr('data-c_id');
var session_id = item.attr('data-session_id');
var f = function(data){
if(data.success){
item.remove();
}
message.update(data);
ui.done(btn);
};
ui.loading(btn);
ui.proxy.remove_by_course(c_id, session_id, f);
};

@ -0,0 +1,88 @@
<?php
namespace Notebook;
use Chamilo;
/**
* Form to upload a CSV file.
*
* @license /licence.txt
* @author Laurent Opprecht <laurent@opprecht.info>
*/
class UploadFileForm extends \FormValidator
{
/**
*
* @param string $action
* @return \Glossary\UploadFileForm
*/
public static function create($action)
{
return new self('upload_file', 'post', $action);
}
function __construct($form_name = 'upload_file', $method = 'post', $action = '', $target = '', $attributes = null, $track_submit = true)
{
parent::__construct($form_name, $method, $action, $target, $attributes, $track_submit);
}
/**
*
*
*/
function init()
{
$form_name = get_lang('Import');
$this->add_header($form_name);
$this->add_hidden(Request::PARAM_SEC_TOKEN, Access::instance()->get_token());
$label = get_lang('File');
$this->add_file('file', $label);
$this->addRule('file', get_lang('ThisFieldIsRequired'), 'required');
$this->add_button('save', get_lang('Save'), array('class' => 'btn save'));
$label = get_lang('CSVMustLookLike');
$label = "$label";
$help = '<pre>
<b>title</b>;<b>description</b>;
"Hello";"Hola";
"Good";"Bueno";
</pre>';
$this->add_html($label . $help);
}
/**
*
* @return object
*/
public function get_file()
{
$result = Request::file('file', array());
if (empty($result)) {
return null;
}
$error = isset($result['error']) ? (bool) $result['error'] : false;
if ($error) {
return array();
}
return (object) $result;
}
public function validate()
{
$result = (bool) parent::validate();
if ($result == false) {
return false;
}
$file = $this->get_file();
if (empty($file)) {
return false;
}
return true;
}
}

@ -0,0 +1,10 @@
{% include 'default/notebook/header.tpl' %}
<div class="actions-bar btn-toolbar" >
<a href = "{{root}}&amp;action=index" class="btn back">
<i class="size-32 icon-back"></i>
</a>
</div>
{{form.return_form()}}

@ -0,0 +1,7 @@
{{javascript}}
<div id="messages">
{% for message in messages %}
{{ message }}
{% endfor %}
</div>

@ -0,0 +1,41 @@
{% include 'default/notebook/header.tpl' %}
{% include 'default/notebook/javascript.tpl' %}
<div class="btn-toolbar actions-bar" >
{% if is_allowed_to_edit %}
<div class="btn-group edit">
<a href="{{root}}&amp;action=add" class="notebook btn new term" title="{{'Add'|get_lang}}">
<i class="size-32 icon-new-note"></i>
</a>
<a href="{{root}}&amp;action=import_csv" class="btn" title="{{'ImportCSV'|get_lang}}">
<i class="size-32 icon-import-csv"></i>
</a>
<a href="{{root}}&amp;action=export_csv" class="btn" title="{{'ExportAsCSV'|get_lang}}">
<i class="size-32 icon-export-csv"></i>
</a>
<a href="javascript:void(0)" onclick="ui.remove_by_course('entries', this);return false;" class="btn delete_all" title="{{'DeleteAll'|get_lang}}">
<i class="size-32 icon-delete-all"></i>
</a>
</div>
{% endif %}
<div class="btn-group sort">
<a href="{{root}}&amp;action=index&amp;sort_column=creation_date&amp;sort_direction={%if sort_direction == 'ASC' and sort_column == 'creation_date' %}DESC{% else %}ASC{% endif %}"
class="btn"
title="{{'SorteByCreatedDate'|get_lang}}">
<i class="size-32 icon-sort-by-created-date"></i>
</a>
<a href="{{root}}&amp;action=index&amp;sort_column=update_date&amp;sort_direction={%if sort_direction == 'ASC' and sort_column == 'update_date' %}DESC{% else %}ASC{% endif %}"
class="btn"
title="{{'SorteByUpdatedDate'|get_lang}}">
<i class="size-32 icon-sort-by-modified-date"></i>
</a>
<a href="{{root}}&amp;action=index&amp;sort_column=title&amp;sort_direction={%if sort_direction == 'ASC' and sort_column == 'title' %}DESC{% else %}ASC{% endif %}"
class="btn"
title="{{'SortByTitle'|get_lang}}">
<i class="size-32 icon-sort-by-title"></i>
</a>
</div>
</div>
{% include 'default/notebook/list.tpl' %}

@ -0,0 +1,27 @@
<script type="text/javascript" src="{{www}}/main/notebook/resources/js/proxy.js"></script>
<script type="text/javascript" src="{{www}}/main/notebook/resources/js/ui.js"></script>
<script type="text/javascript">
$(function() {
ui.proxy = notebook;
window.context = {};
context.sec_token = '{{sec_token}}';
context.c_id = '{{c_id}}';
context.session_id = '{{session_id}}';
context.www = '{{www}}';
context.ajax = '{{www}}/main/inc/ajax/notebook.ajax.php';
if(typeof(lang) == "undefined")
{
window.lang = {};
}
lang.ConfirmYourChoice = "{{'ConfirmYourChoice'|get_lang}}";
});
</script>

@ -0,0 +1,32 @@
<ul id="entries" class="notebook entries unstyled" data-c_id="{{c_id}}" data-session_id="{{session_id}}" >
{% for item in items %}
<li id="notebook_{{item.id}}" class="notebook note" data-id="{{item.id}}" data-c_id="{{item.c_id}}" data-type="notebook">
<div class="title sectiontitle">
{% if is_allowed_to_edit %}
<div class="pull-right element-actions">
<a href="{{root}}&amp;action=edit&amp;id={{item.id}}"
title="{{'Edit'|get_lang}}">
<i class="size-22 icon-edit"></i>
</a>
<a href="{{root}}&amp;action=delete&amp;id={{item.id}}"
onclick="ui.remove('notebook_{{item.id}}', this); return false;"
title="{{'Delete'|get_lang}}">
<i class="size-22 icon-delete"></i>
</a>
</div>
{% endif %}
{{item.title}}
{% if item.session_id %}
{{session_image}}
{% endif %}
</div>
<div class="sectioncomment">
{{item.description}}
</div>
<div class="sectionfooter footer">{{item.update_date|date}}</div>
</li>
{% endfor %}
</ul>

@ -0,0 +1,9 @@
{% include 'default/notebook/header.tpl' %}
<div class="actions-bar btn-toolbar" >
<a href = "{{root}}&amp;action=index" class="btn back">
<i class="size-32 icon-back"></i>
</a>
</div>
{{form.return_form()}}
Loading…
Cancel
Save