Wednesday 4 November 2015

Moodle: Avoid alert message when form changed and exit page

Hello,

Sometimes in a moodleform you want to move to another page by javascript and a message appears saying "Are you sure...?"

The solution:

In your javascript code, use before call window.location:

window.onbeforeunload = null; 

Best regards!

UPDATE 09/3/2015
P.D: Another option is editing the form and in the definition function add:

public function definition() {
        $mform =& $this->_form;
        $mform->disable_form_change_checker();

Tuesday 13 October 2015

Moodle: Change current session lang in your local plugins

Hi,

I'm creating some code in my moodle local plugins and webservices and I'd like to "force" use a specific language. The solution that I found is:

$SESSION->lang = 'ca';

Best regards,
Iban Cardona.

Saturday 10 October 2015

Laravel & TDD: Only test 1 file or function

Hello,

I'm developing with Laravel 5.1 and creating some testing files... http://laravel.com/docs/5.1/testing

I can test all my code executing phpunit inside my project folder but how test only one file/function:

- 1 file: phpunit tests/Auth/UserTest.php
- 1 function: phpunit --filter testRegisterControllerUser tests/Auth/UserTest.php

Best regards,
Iban Cardona.

Friday 2 October 2015

Using Testing Environment with PHPunit and Laravel

Hello,

Recently I've been using phpunit with Laravel and I found this problem: How to clean or reset my test environment on every test? I did this solution:

Laravel version : 5.1

I followed this tutorial: http://laravel.com/docs/5.1/testing

I created my .env.testing file:

APP_ENV=testing
APP_DEBUG=true
APP_KEY=app_key_testing

DB_CONNECTION=mysql_testing
DB_HOST=localhost
DB_DATABASE=test
DB_USERNAME=dbusernametest
DB_PASSWORD=dbpwdtest

I changed my TestCase.php file:

class TestCase extends Illuminate\Foundation\Testing\TestCase
{
    /**
     * The base URL to use while testing the application.
     *
     * @var string
     */
    protected $baseUrl = 'http://localhost';

    /**
     * Creates the application.
     *
     * @return \Illuminate\Foundation\Application
     */
    public function createApplication()
    {
        $app = require __DIR__.'/../bootstrap/app.php';

        $app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();

        return $app;
    }

    public function setUp()
    {
        exec('cp /opt/lampp/htdocs/mytestsite/.env.testing /opt/lampp/htdocs/mytestsite/.env');
        parent::setUp();
        Artisan::call('migrate');
    }

    public function tearDown()
    {
        Artisan::call('migrate:reset');
        parent::tearDown();
        exec('cp /opt/lampp/htdocs/mytestsite/.env.local /opt/lampp/htdocs/mytestsite/.env');
    }
}

I hope you find it useful.

Best regards!

Saturday 19 September 2015

Install XAMPP + Laravel in Ubuntu

Hello,

Ubuntu version: 14.04.3 LTS
XAMPP version: 5.6.15
Laravel version: 5.2

Install XAMPP (as root)
  • chmod +x xampp-linux-x64-5.6.12-0-installer.run
  • ./xampp-linux-x64-5.6.8-0-installer.run
  • You will be asked to answer some questions, I sayed always Y.
  • To start lampp server: /opt/lampp/lampp start
Install Laravel (as root)
  • Install composer: curl -sS https://getcomposer.org/installer | /opt/lampp/bin/php -- --install-dir=/opt/lampp/bin --filename=composer
  • cd /opt/lampp/htdocs
  • export PATH="$PATH:$HOME/.composer/vendor/bin"
  • export PATH=$PATH:/opt/lampp/bin
  • composer global require "laravel/installer"
  • laravel new test
  • chmod 777 /opt/lampp/htdocs/test/bootstrap/cache
  • chmod -R 777 /opt/lampp/htdocs/test/storage/*
Config Virtual Hosts (as root)
  • vim /opt/lampp/etc/httpd.conf
  • #Include etc/extra/httpd-vhosts.conf --> Include etc/extra/httpd-vhosts.conf
  • Add in /opt/lampp/etc/extra/httpd-vhosts.conf
    •  <VirtualHost *:80>
          ServerAdmin webmaster@dummy-host.example.com
          DocumentRoot "/opt/lampp/htdocs/test/public"
          ServerName testlaravel.com
          ServerAlias www.testlaravel.com
          ErrorLog "logs/testlaravel-error_log"
          CustomLog "logs/testlaravel-access_log" common
      </VirtualHost>
  • /opt/lampp/lampp restart
  • Add in  /etc/hosts
    • 127.0.0.1       testlaravel.com
    • 127.0.0.1       www.testlaravel.com
Done! Go to your browser and write: testlaravel.com...

Tuesday 30 June 2015

Postgres: could not open file "/etc/ssl/certs/ssl-cert-snakeoil.pem"

Hello,

Today I had a problem starting PostgreSQL server. I saw this error:

* The PostgreSQL server failed to start. Please check the log output:
CEST FATAL:  could not open file "/etc/ssl/certs/ssl-cert-snakeoil.pem"


To solve it I did these actions:

cd /etc/ssl/certs/
chown postgres ssl-cert-snakeoil.pem
chmod 777 ssl-cert-snakeoil.pem

cd /etc/ssl/private
chown postgres ssl-cert-snakeoil.key
chmod 700 ssl-cert-snakeoil.key

Best regards!!!

Wednesday 17 June 2015

Essential: List of categories as a tree

Essential is a fancy moodle theme that has a lot of settings... One of them is use icons in categories or not. If you select in Category Icons -> Enable category icons : Yes, you will see categories as folders:

If you select "No", you will see categories as a tree:

Best regards,
Iban Cardona.

Monday 8 June 2015

Using fputcsv without enclosure

Hi,

If you want to use the PHP function fputcsv in order to create a CSV file using no character as enclosure, you can write:

$list = array (
    array('aaa', 'bbb', 'ccc', 'dddd')
);

$fp = fopen('file.csv', 'w');

foreach ($list as $fields) {
    fputcsv($fp, $fields, ';', '');
}

But a warning will appear:

PHP Warning:  fputcsv(): enclosure must be a character

To avoid it, you need to write:

$list = array (
    array('aaa', 'bbb', 'ccc', 'dddd')
);

$fp = fopen('file.csv', 'w');

foreach ($list as $fields) {
    fputcsv($fp, $fields, ';', chr(0));
}

Best regards,
Iban Cardona.

Monday 23 March 2015

Use image repository in theme settings inside html editor

Hi,

I'm using Essential (version 2.7) theme in moodle. In settings section, I'd like to use html editor with the option to upload images. My solution:

In settings.php file:

global $CFG;
require_once($CFG->dirroot.'/local/icsbcn/lib/admin_setting_confightmleditor_icsbcn.class.php');
$setting = new admin_setting_confightmleditor_icsbcn($name, $title, $description, $default);

In admin_setting_confightmleditor_icsbcn.class.php file:

<?php
global $CFG;
require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/filelib.php');

/**
 * General text area with html editor.
 */
class admin_setting_confightmleditor_icsbcn extends admin_setting_configtext {
    private $rows;
    private $cols;
    private $options;

    /**
     * @param string $name
     * @param string $visiblename
     * @param string $description
     * @param mixed $defaultsetting string or array
     * @param mixed $paramtype
     */
    public function __construct($name, $visiblename, $description, $defaultsetting, $paramtype=PARAM_RAW, $cols='60', $rows='8') {
        $this->rows = $rows;
        $this->cols = $cols;
        parent::__construct($name, $visiblename, $description, $defaultsetting, $paramtype);
        editors_head_setup();
    }

    private function get_options() {
        global $USER;

        $ctx = context_user::instance($USER->id);
        $default = array();
        $default['noclean'] = false;
        $default['context'] = $ctx;
        $default['maxbytes'] = 0;
        $default['maxfiles'] = -1;
        $default['forcehttps'] = false;
        $default['subdirs'] = false;
        $default['changeformat'] = 0;
        $default['areamaxbytes'] = FILE_AREA_MAX_BYTES_UNLIMITED;
        $default['return_types'] = (FILE_INTERNAL | FILE_EXTERNAL);

        return $default;
    }

    /**
     * Returns an XHTML string for the editor
     *
     * @param string $data
     * @param string $query
     * @return string XHTML string for the editor
     */
    public function output_html($data, $query='') {
        global $USER;

        $default = $this->get_defaultsetting();

        $defaultinfo = $default;
        if (!is_null($default) and $default !== '') {
            $defaultinfo = "\n".$default;
        }

        $ctx = context_user::instance($USER->id);
        $editor = editors_get_preferred_editor(FORMAT_HTML);
        $options = $this->get_options();
        $draftitemid = file_get_unused_draft_itemid();
        $component = is_null($this->plugin) ? 'core' : $this->plugin;
        $data = file_prepare_draft_area($draftitemid, $options['context']->id, $component, $this->get_full_name().'_draftitemid', $draftitemid, $options, $data);
        
        $fpoptions = array();
        $args = new stdClass();
        // need these three to filter repositories list
        $args->accepted_types = array('web_image');
        $args->return_types = $options['return_types'];
        $args->context = $ctx;
        $args->env = 'filepicker';
        // advimage plugin
        $image_options = initialise_filepicker($args);
        $image_options->context = $ctx;
        $image_options->client_id = uniqid();
        $image_options->maxbytes = $options['maxbytes'];
        $image_options->areamaxbytes = $options['areamaxbytes'];
        $image_options->env = 'editor';
        $image_options->itemid = $draftitemid;

        // moodlemedia plugin
        $args->accepted_types = array('video', 'audio');
        $media_options = initialise_filepicker($args);
        $media_options->context = $ctx;
        $media_options->client_id = uniqid();
        $media_options->maxbytes  = $options['maxbytes'];
        $media_options->areamaxbytes  = $options['areamaxbytes'];
        $media_options->env = 'editor';
        $media_options->itemid = $draftitemid;

        // advlink plugin
        $args->accepted_types = '*';
        $link_options = initialise_filepicker($args);
        $link_options->context = $ctx;
        $link_options->client_id = uniqid();
        $link_options->maxbytes  = $options['maxbytes'];
        $link_options->areamaxbytes  = $options['areamaxbytes'];
        $link_options->env = 'editor';
        $link_options->itemid = $draftitemid;

        $fpoptions['image'] = $image_options;
        $fpoptions['media'] = $media_options;
        $fpoptions['link'] = $link_options;
        
        $editor->use_editor($this->get_id(), $options, $fpoptions);

        return format_admin_setting($this, $this->visiblename,
        '<div class="form-textarea"><textarea rows="'. $this->rows .'" cols="'. $this->cols .'" id="'. $this->get_id() .'" name="'. $this->get_full_name() .'" spellcheck="true">'. s($data) .'</textarea></div>
        <input value="'.$draftitemid.'" name="'.$this->get_full_name().'_draftitemid" type="hidden" />',
        $this->description, true, '', $defaultinfo, $query);
    }

    public function write_setting($data) {
        global $CFG;

        if ($this->paramtype === PARAM_INT and $data === '') {
        // do not complain if '' used instead of 0
            $data = 0;
        }
        // $data is a string
        $validated = $this->validate($data);
        if ($validated !== true) {
            return $validated;
        }

        $options = $this->get_options();
        $fs = get_file_storage();
        $component = is_null($this->plugin) ? 'core' : $this->plugin;
        $wwwroot = $CFG->wwwroot;
        if ($options['forcehttps']) {
            $wwwroot = str_replace('http://', 'https://', $wwwroot);
        }

        $draftitemid = $_REQUEST[$this->get_full_name().'_draftitemid'];
        $draftfiles = $fs->get_area_files($options['context']->id, 'user', 'draft', $draftitemid, 'id');
        foreach ($draftfiles as $file) {
            if (!$file->is_directory()) {
                $strToSearch = "$wwwroot/draftfile.php/".$options['context']->id."/user/draft/$draftitemid/".$file->get_filename();
                if (stripos($data, $strToSearch) !== false) {
                    $file_record = array(
                        'contextid' => context_system::instance()->id,
                        'component' => $component,
                        'filearea' => 'icsbcnmarketingimages',
                        'itemid' => 0,
                        'timemodified' => time()
                    );
                    $newfile = $fs->create_file_from_storedfile($file_record, $file);
                    $url = moodle_url::make_pluginfile_url($newfile->get_contextid(), $newfile->get_component(), $newfile->get_filearea(), $newfile->get_itemid(), $newfile->get_filepath(), $newfile->get_filename());
                    $data = str_ireplace($strToSearch, $url, $data);
                }
            }
        }
        
        return ($this->config_write($this->name, $data) ? '' : get_string('errorsetting', 'admin'));
    }
}

In theme/icsbcn/lib.php:

I added these lines in function theme_icsbcn_pluginfile:
else if ($filearea === 'icsbcnmarketingimages') { 
            return $theme->setting_file_serve($filearea, $args, $forcedownload, $options);
        }

Best regards!
Iban Cardona.

Saturday 31 January 2015

Easy clock with Javascript (jQuery)

Hello,

An easy and fast way to develope a clock that is updated every minute:

<div class="clock">
<i class="fa fa-clock-o"> </i><span>15:51</span><script type="text/javascript">
var intervalclock = 0;
function startClock() {
  setTimeout(function() {
    print_clock();
    intervalclock = 60;
    setInterval(function() {
      print_clock();
    }, intervalclock * 1000);
  }, intervalclock * 1000);
}
    
function print_clock() {
  var now = new Date();
  var hour = now.getHours();
  var minute = now.getMinutes();
  if (minute < 10) { minute = "0" + minute; };
  var timeString = hour + ':' + minute;
  $('.clock\ > span').text(timeString);
}
    
$(window).load(function() {
  var timeclock = new Date();
  intervalclock = 60 - timeclock.getSeconds();
  if(intervalclock == 60) {
    intervalclock = 0;
  }
  startClock();
});
</script>
</div>

Best regards!

Thursday 8 January 2015

Moodle: Number of courses in which a user is enrolled

Hello,

Moodle is a software designed to create online courses. You can add a lot of tailor-made plugins.

One of the most interesting info that would be interesting could be... The number of courses in which a user is enrolled. We can know it by (tested with version 2.6.2):

global $DB;
$sql_count = 'SELECT COUNT(c.id)
FROM mdl_course AS c
JOIN mdl_context AS ct ON c.id = ct.instanceid
JOIN mdl_role_assignments AS ra ON ra.contextid = ct.id
JOIN mdl_user AS u ON u.id = ra.userid
JOIN mdl_role AS r ON r.id = ra.roleid
WHERE u.id = ?';
$courses_count = $DB->count_records_sql($sql_count, array($idUser));


Regards!

Friday 2 January 2015

tt_news: Modify query to database

tt_news is an extension of TYPO3 designed to publish news in our website. It's a very popular extension and it allows publish and manage news about our company, association, etc. You can find extension manual here.

Suppose that we have our own extension with our own plugins and we want to indicate that in the news list we only want news with ID greater than 100... So we should use a hook that is prepared for the extension in order to modify the database query.

In this example we used TYPO3 4.4.4 and tt_news 3.0.1. Files to modify are:
ext_localconf.php

if (TYPO3_MODE == 'FE')  { require_once(t3lib_extMgm::extPath('user_t3_test').'user_t3_test_selectHook.php'); }
$TYPO3_CONF_VARS['EXTCONF']['tt_news']['selectConfHook'][] = 'user_t3_test_selectHook';


user_t3_test_selectHook.php

class user_t3_test_selectHook {
public function processSelectConfHook(&$parentObject, $selectConf) {
$selectConf['where'] .= ' AND uid > 100 ';
return $selectConf;
}


I hope you find it useful! Regards!

Thursday 1 January 2015

Overwrite title tag with TypoScript

TYPO3 is a powerful CMS that uses its own configuration language called TypoScript. This article does not explain what or how to configure TYPO3. In this case only show you how to override the title tag of a page using TypoScript. To develop this example we used a quite old version of TYPO3: 4.2.14 but this solution is also valid for newer versions. Suppose we want new title "Test", then the TypoScript of our template should be:
config.noPageTitle = 2
page = PAGE
page.headerData.10 = TEXT
page.headerData.10.wrap = <title>Test</title>
In the first line we say that we don't want to print the default title. More info here. In the other 3 lines we change the page header adding our title. I hope you find it useful! Regards!