skala
Laurent Opprecht 14 years ago
commit eea2e3ecd3
  1. 220
      main/css/base.css
  2. BIN
      main/img/sort_asc.png
  3. BIN
      main/img/sort_desc.png
  4. 7
      main/inc/ajax/glossary.ajax.php
  5. 203
      main/inc/lib/access.class.php
  6. 57
      main/inc/lib/ajax_controller.class.php
  7. 198
      main/inc/lib/controller.class.php
  8. 30
      main/inc/lib/entity.class.php
  9. 95
      main/inc/lib/file_store.class.php
  10. 129
      main/inc/lib/system/io/csv_object_writer.class.php
  11. 6
      main/inc/lib/system/io/csv_writer.class.php

@ -3978,6 +3978,21 @@ footer {
box-shadow:none;
}
.btn.loading{
border:none;
border-radius: 0;
background-color: transparent;
width:22px;
height:22px;
margin:0;
padding:0;
display:inline-block;
background-image: url('../img/loading1.gif') !important;
background-repeat: no-repeat;
background-position:center center;
box-shadow:none;
}
.announce.btn.delete-all{
border:none;
border-radius: 0;
@ -4038,6 +4053,36 @@ footer {
box-shadow:none;
}
.btn.import_csv{
border:none;
border-radius: 0;
background-color: transparent;
width:32px;
height:32px;
margin:0;
padding:0;
display:inline-block;
background-image: url('../img/icons/32/import_csv.png');
background-repeat: no-repeat;
background-position:center center;
box-shadow:none;
}
.btn.delete_all{
border:none;
border-radius: 0;
background-color: transparent;
width:32px;
height:32px;
margin:0;
padding:0;
display:inline-block;
background-image: url('../img/icons/32/delete.png');
background-repeat: no-repeat;
background-position:center center;
box-shadow:none;
}
.btn.expand{
border:none;
border-radius: 0;
@ -4068,7 +4113,7 @@ footer {
box-shadow:none;
}
.announce.btn.new{
.btn.back{
border:none;
border-radius: 0;
background-color: transparent;
@ -4077,12 +4122,13 @@ footer {
margin:0;
padding:0;
display:inline-block;
background-image: url('../img/icons/32/new_announce.png');
background-image: url('../img/icons/32/back.png');
background-repeat: no-repeat;
background-position:center center;
box-shadow:none;
}
.announce.btn.back{
.btn.view.detailed{
border:none;
border-radius: 0;
background-color: transparent;
@ -4091,14 +4137,44 @@ footer {
margin:0;
padding:0;
display:inline-block;
background-image: url('../img/icons/32/back.png');
background-image: url('../img/icons/32/view_detailed.png');
background-repeat: no-repeat;
background-position:center center;
box-shadow:none;
}
.btn.view.text{
border:none;
border-radius: 0;
background-color: transparent;
width:32px;
height:32px;
margin:0;
padding:0;
display:inline-block;
background-image: url('../img/icons/32/view_text.png');
background-repeat: no-repeat;
background-position:center center;
box-shadow:none;
}
.announce.btn.new{
border:none;
border-radius: 0;
background-color: transparent;
width:32px;
height:32px;
margin:0;
padding:0;
display:inline-block;
background-image: url('../img/icons/32/new_announce.png');
background-repeat: no-repeat;
background-position:center center;
box-shadow:none;
}
.announcement {
/* background: none repeat scroll 0 0 #F2F2F2;*/
/* background: none repeat scroll 0 0 #F2F2F2;*/
border: 1px solid #D3D3D3;
color: #555555;
font-weight: normal;
@ -4109,8 +4185,8 @@ footer {
width: 100%;
}
.announcement .title{
background: none repeat scroll 0 0 #F2F2F2;
color:black;
background: none repeat scroll 0 0 #F2F2F2;
color:black;
}
.announcement .title a:link,
@ -4152,6 +4228,10 @@ li.annoucement{
cursor: pointer;
}
/*
link
*/
.link_category{
background-color: #FFFFFF;
margin-bottom: 5px;
@ -4225,6 +4305,63 @@ li.annoucement{
color: #999999;
}
.link .status{
border:none;
border-radius: 0;
background-color: transparent;
width:22px;
height:22px;
margin:0;
padding:0;
display:inline-block;
background-repeat: no-repeat;
background-position:center center;
box-shadow:none;
}
.link.invalid .status{
background-image: url('../img/icons/22/error.png');
}
.link.valid .status{
background-image: url('../img/icons/22/accept.png');
}
.btn.validate_link{
border:none;
border-radius: 0;
background-color: transparent;
width:22px;
height:22px;
margin:0;
padding:0;
display:inline-block;
background-image: url('../img/icons/22/preview_view.png');
background-repeat: no-repeat;
background-position:center center;
box-shadow:none;
}
/*
Glossary
*/
.glossary.btn.new.term{
border:none;
border-radius: 0;
background-color: transparent;
width:32px;
height:32px;
margin:0;
padding:0;
display:inline-block;
background-image: url('../img/icons/32/new_glossary_term.png');
background-repeat: no-repeat;
background-position:center center;
box-shadow:none;
}
#learning_path_main #control {
text-align: center;
background-image:-webkit-gradient(linear,left top,left bottom,from(#ececec),to(#fff));
@ -4233,7 +4370,7 @@ li.annoucement{
background-image:-ms-linear-gradient(top,#ececec,#fff);
background-image:-o-linear-gradient(top,#ececec,#fff);
background-image:linear-gradient(top,#ececec,#fff);
height:32px;
padding:8px 0px 8px 0px;
opacity:0.9;
@ -4245,6 +4382,73 @@ li.annoucement{
}
/*
data table
*/
.dataTables_wrapper{
clear: both;
}
.dataTables_length {
float: left;
width: 40%;
}
.dataTables_filter {
text-align: right;
}
.dataTables_info {
float: left;
width: 60%;
}
.dataTables_paginate {
float: right;
text-align: right;
}
.dataTables_wrapper label input, .dataTables_wrapper label textarea, .dataTables_wrapper label select {
display: inline-block;
}
.dataTables.display {
clear: both;
margin: 0 auto;
width: 100%;
}
.dataTables_wrapper .paginate_disabled_previous, .dataTables_wrapper .paginate_enabled_previous {
padding-left: 23px;
background: url("../img/action_prev.png") no-repeat scroll left top;
}
.dataTables_wrapper .paginate_disabled_next, .dataTables_wrapper .paginate_enabled_next {
margin-left: 10px;
padding-right: 23px;
background: url("../img/action_next.png") no-repeat scroll left top;
}
.dataTables_wrapper .paginate_disabled_previous, .dataTables_wrapper .paginate_disabled_next{
opacity: 0.4;
}
.dataTables_wrapper .sorting_asc {
background-image: url("../img/sort_asc.png");
background-repeat: no-repeat;
background-attachment: scroll;
background-position: right center;
}
.dataTables_wrapper .sorting_desc{
background-image: url("../img/sort_desc.png");
background-repeat: no-repeat;
background-attachment: scroll;
background-position: right center;
}
#course_category_well {
padding: 9px 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 879 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 877 B

@ -0,0 +1,7 @@
<?php
namespace Glossary;
require_once '../global.inc.php';
AjaxController::instance()->run();

@ -0,0 +1,203 @@
<?php
/**
* Authorize or deny calls.
*
*
* Note:
*
* This class stores locally the security token so that the current call
* can still be validated after generating the new token.
*
* The new security token is generated only on first call. Successive calls
* return the same token. This ensure that different parts of the application
* (form, javascript for javascript, etc) can get access to the same token.
*
* @author Laurent Opprecht <laurent@opprecht.info> for the Univesity of Geneva
* @license /license.txt
*/
abstract class Access
{
const SEC_TOKEN = 'sec_token';
/**
* Return view and edit access.
*
* @return \Access
*/
public static function all()
{
return AccessAll::instance();
}
/**
* Return no access.
*
* @return \Access
*/
public static function forbidden()
{
AccessForbidden::instance();
}
protected $session_token;
protected $token;
/**
* Returns true if security token is valid, false otherwise.
*
* @return bool
*/
public function is_token_valid()
{
$call_token = Request::get_security_token();
if (empty($call_token)) {
return false;
}
$session_token = $this->get_session_token();
return $session_token == $call_token;
}
/**
* Returns the token contained in the session.
* Stores the token for further reuse so that it can be changed in session.
*
* @return string
*/
public function get_session_token()
{
if (empty($this->session_token)) {
$key = self::SEC_TOKEN;
$this->session_token = isset($_SESSION[$key]) ? $_SESSION[$key] : '';
}
return $this->session_token;
}
/*
* On first call generate a new security token and save it in session.
* On successful calls returns the same (new) token (function is repeatable).
* If user do not have the right to edit, returns a blank (invalid) token.
*
* Stores the existing session token before saving the new one so that
* the current call can still be validated after calling this function.
*/
public function get_token()
{
if (!$this->can_edit()) {
return '';
}
if ($this->token) {
return $this->token;
}
$this->session_token = $this->get_session_token();
$this->token = \Security::get_token();
}
/**
* Returns true if the user has the right to edit.
*
* @return boolean
*/
public abstract function can_edit();
/**
* Returns true if the current user has the right to view
*
* @return boolean
*/
public abstract function can_view();
public function authorize()
{
return $this->can_view();
}
}
/**
* Authorize access and view access.
*/
class AccessAll extends Access
{
/**
* Return the instance.
*
* @return \Access
*/
public static function instance()
{
static $result = null;
if (empty($result)) {
$result = new self();
}
return $result;
}
private function __construct()
{
}
public function can_edit()
{
return true;
}
public function can_view()
{
return true;
}
public function authorize()
{
return true;
}
}
/**
* Authorizev view access only
*/
class AccessForbidden extends Access
{
/**
* Return the instance.
*
* @return \AccessView
*/
public static function instance()
{
static $result = null;
if (empty($result)) {
$result = new self();
}
return $result;
}
private function __construct()
{
}
public function can_edit()
{
return false;
}
public function can_view()
{
return false;
}
public function authorize()
{
return false;
}
}

@ -0,0 +1,57 @@
<?php
/**
* Ajax controller. Dispatch request and perform required action.
*
*
* Usage:
*
* $controller = AjaxController::instance();
* $controller->run();
*
* @author Laurent Opprecht <laurent@opprecht.info> for the Univesity of Genevas
* @license /license.txt
*/
class AjaxController extends \Controller
{
function forbidden()
{
$this->response(false, get_lang('YourAreNotAuthorized'));
}
public function unknown()
{
$this->response(false, get_lang('UnknownAction'));
}
/**
* Action exists but implementation is missing.
*/
public function missing()
{
$this->response(false, get_lang('NoImplementation'));
}
/**
* Display a standard json responce.
*
* @param bool $success
* @param string $message
* @param object $data
*/
public function response($success = false, $message = '', $data = null)
{
$message = trim($message);
$response = (object) array();
$response->success = $success;
if ($message) {
$response->message = Display::return_message($message, $success ? 'normal' : 'error');
} else {
$response->message = '';
}
$response->data = $data;
$this->render_json($response);
}
}

@ -0,0 +1,198 @@
<?php
/**
* Controller
*
*
*
* @author Laurent Opprecht <laurent@opprecht.info> for the Univesity of Genevas
* @license see /license.txt
*/
class Controller
{
const PARAM_ACTION = 'action';
protected $access;
protected function __construct($access = null)
{
$access = $access ? $access : Access::all();
$this->access = $access;
}
/**
*
* @return \Access
*/
public function access()
{
return $this->access;
}
/**
* List of actions accepted by the controller.
*
* @return array
*/
public function get_actions()
{
$reflector = new ReflectionClass($this);
$constants = $reflector->getConstants();
$result = array();
foreach ($constants as $key => $value) {
if (strpos($key, 'ACTION') !== false) {
$result[$key] = $value;
}
}
return $result;
}
/**
* Action to perform.
* Returns the request parameter.
*
* @return string
*/
public function get_action()
{
$result = Request::get(self::PARAM_ACTION);
$actions = $this->get_actions();
$result = in_array($result, $actions) ? $result : '';
return $result;
}
/**
* Set up the environment. Set up breadcrumps, raise tracking event, etc.
*/
protected function prolog()
{
}
/**
* Whether the call is authorized or not.
*
* @return boolean
*/
public function authorize()
{
return $this->access()->authorize();
}
/**
* Returns a string containing dynamic javascript to be included in the template.
* This requires a {{javascript}} tag in a twigg template to appear.
*
* Note:
*
* A better approach to this method is to create a twigg "javascript"
* template and to include it where required.
*
* @return string
*/
public function javascript()
{
return '';
}
// public function check_token()
// {
// return (bool) Security::check_token('get');
// }
/**
* Run the controller. Dispatch action and execute requested tasks.
*/
public function run()
{
if (!$this->authorize()) {
$this->forbidden();
return false;
}
$this->prolog();
$action = $this->get_action();
if (empty($action)) {
$this->unknown();
return;
}
$f = array($this, $action);
if (is_callable($f)) {
call_user_func($f);
} else {
$this->missing();
}
}
/**
* Unknown action. I.e. the action has not been registered.
* Possibly missing action declaration:
*
* const ACTION_XXX = 'XXX';
*
* @return boolean
*/
public function unknown()
{
return false;
}
/**
*
* @return boolean
*/
public function forbidden()
{
api_not_allowed();
return false;
}
/**
* Action exists but implementation is missing.
*/
public function missing()
{
echo 'No implementation';
return false;
}
/**
* Render a template using data. Adds a few common parameters to data.
*
* @see /main/template/default/course_description/
* @param string $template
* @param array $data
*/
protected function render($template_name, $data)
{
$data = (object) $data;
$data->www = \Chamilo::url();
$data->messages = isset($data->messages) ? $data->messages : array();
$javascript = $this->javascript();
if ($javascript) {
$data->javascript = $javascript;
}
$tpl = new Template();
foreach ($data as $key => $value) {
$tpl->assign($key, $value);
}
$template = $tpl->get_template($template_name);
$content = $tpl->fetch($template);
$tpl->assign('content', $content);
$tpl->display_one_col_template();
}
/**
* Render data as JSON
*
* @param any $data
*/
protected function render_json($data)
{
Header::content_type_json();
echo json_encode($data);
}
}

@ -41,11 +41,39 @@ class Entity
return $result;
}
public function __construct()
function __construct($data = null)
{
if ($data) {
foreach ($this as $key => $value) {
if (isset($data->{$key})) {
$this->{$key} = $data->{$key};
}
}
}
$this->defaults('session_id', api_get_session_id());
}
function __get($name)
{
$f = array($this, "get_$name");
return call_user_func($f);
}
function __isset($name)
{
$f = array($this, "get_$name");
return is_callable($f);
}
function __set($name, $value)
{
$f = array($this, "set_$name");
if (!is_callable($f)) {
return;
}
call_user_func($f, $value);
}
function before_save()
{
$repo = $this->repository();

@ -0,0 +1,95 @@
<?php
/**
*
* @copyright (c) 2012 University of Geneva
* @license GNU General Public License - http://www.gnu.org/copyleft/gpl.html
* @author Laurent Opprecht <laurent@opprecht.info>
*/
class FileStore
{
/**
*
* @param int $c_id
* @param string $sub_path
* @return FileStore
*/
static function course($c_id, $sub_path = '')
{
$sys_path = api_get_path(SYS_COURSE_PATH);
$course = api_get_course_info_by_id($c_id);
$course_path = $course['path'];
$path = $sys_path . $course_path . $sub_path;
if (!is_dir($path)) {
$mode = api_get_permissions_for_new_directories();
$success = mkdir($path, $mode, true);
if (!$success) {
return false;
}
}
return new self($path);
}
protected $root = '';
public function __construct($root)
{
$root = ltrim($root, '/');
$root .= '/';
$this->root = $root;
}
public function root()
{
return $this->root;
}
function accept($filename)
{
return (bool) filter_extension($filename);
}
function add($path)
{
$root = $this->root();
$id = $this->new_id();
$new_path = "$root/$id";
$success = @move_uploaded_file($path, $new_path);
return $success ? $id : false;
}
function remove($path){
$root = $this->root();
$full_path = "$root/$path";
if(is_file($full_path)){
$result = unlink($full_path);
return $result;
}
return false;
}
function get($id)
{
$root = $this->root();
$result = "$root/$id";
return $result;
}
function new_id()
{
$root = $this->root();
$id = uniqid('');
$path = "$root/$id";
while (file_exists($path)) {
$id = uniqid('');
$path = "$root/$id";
}
return $id;
}
}

@ -0,0 +1,129 @@
<?php
/**
* Write objects to a stream in csv format based on map.
*
* Usage
*
* $object->property_name_1 = 'name 1';
* $object->property_name_2 = 'name 2';
*
* $map = array( 'property_name_1' => 'Header title 1',
* 'property_name_2' => 'Header title 2');
*
* $writer = CsvObjectWriter::create($map, 'temp');
* $writer->add($object);
*
* Output
*
* "Header title 1";"Header title 2"
* "name 1";"name 2"
*
* @license /licence.txt
* @author Laurent Opprecht <laurent@opprecht.info>
*/
class CsvObjectWriter extends CsvWriter
{
/**
*
* @param string|object $stream
* @return CsvWriter
*/
static function create($stream, $map = '*', $delimiter = ';', $enclosure = '"')
{
return new self($stream, $map = '*', $map, $delimiter, $enclosure);
}
protected $map = '*';
protected $headers_written = false;
function __construct($stream, $map = '*', $delimiter = ';', $enclosure = '"')
{
parent::__construct($stream, $delimiter, $enclosure);
$this->map = $map;
}
public function get_map()
{
return $this->map;
}
/**
*
* @param object $item
* @return boolean
*/
public function put($item)
{
$data = $this->convert($item);
if (empty($data)) {
return false;
}
$this->writer_headers();
parent::put($data);
return true;
}
/**
* Convert object to array of data
* @param object $object
* @return array
*/
protected function convert($item)
{
$result = array();
$map = $this->map;
if ($map == '*') {
return (array) $item;
}
foreach ($map as $key => $value) {
$result[$key] = isset($item->{$key}) ? $item->{$key} : '';
}
return $result;
}
/**
*
* @param array $items
*/
public function add_all($items)
{
foreach ($items as $item) {
$this->add($item);
}
}
/**
*
* @param array|object $item
*/
public function add($item)
{
if (is_array($item)) {
$this->add_all($item);
return;
}
$this->put($item);
}
protected function writer_headers()
{
if ($this->headers_written) {
return;
}
$this->headers_written = true;
$map = $this->map;
if (!is_array($map)) {
return;
}
$headers = array();
foreach ($map as $key => $value) {
$headers[] = $value;
}
parent::put($headers);
}
}

@ -46,7 +46,11 @@ class CsvWriter
{
return $this->enclosure;
}
function get_stream(){
return $this->stream;
}
/**
*
* @return FileWriter

Loading…
Cancel
Save