Merge branch 'wip-MDL-29731-master' of git://github.com/marinaglancy/moodle
authorDan Poltawski <dan@moodle.com>
Mon, 29 Jul 2013 05:20:59 +0000 (13:20 +0800)
committerDan Poltawski <dan@moodle.com>
Mon, 29 Jul 2013 05:20:59 +0000 (13:20 +0800)
34 files changed:
cache/stores/file/lib.php
cache/tests/cache_test.php
grade/report/user/lib.php
lang/en/admin.php
lang/en/install.php
lib/db/upgrade.php
lib/db/upgradelib.php
lib/ddl/mssql_sql_generator.php
lib/dml/moodle_database.php
lib/dml/mssql_native_moodle_database.php
lib/dml/mysqli_native_moodle_database.php
lib/dml/oci_native_moodle_database.php
lib/dml/pdo_moodle_database.php
lib/dml/pgsql_native_moodle_database.php
lib/dml/sqlsrv_native_moodle_database.php
lib/dml/tests/dml_test.php
lib/modinfolib.php
lib/outputrequirementslib.php
lib/setuplib.php
lib/upgrade.txt
mod/assign/externallib.php
mod/assignment/lib.php
mod/chat/gui_ajax/module.js
mod/chat/gui_ajax/theme/bubble/chat.css
mod/chat/styles.css
mod/feedback/lib.php
mod/label/lib.php
mod/lti/lib.php
mod/lti/locallib.php
mod/lti/service.php
mod/page/lib.php
mod/resource/lib.php
mod/url/lib.php
version.php

index 96d11b2..adc1a9b 100644 (file)
@@ -266,7 +266,7 @@ class cachestore_file extends cache_store implements cache_is_key_aware, cache_i
         $this->definition = $definition;
         $hash = preg_replace('#[^a-zA-Z0-9]+#', '_', $this->definition->get_id());
         $this->path = $this->filestorepath.'/'.$hash;
-        make_writable_directory($this->path);
+        make_writable_directory($this->path, false);
         if ($this->prescan && $definition->get_mode() !== self::MODE_REQUEST) {
             $this->prescan = false;
         }
@@ -314,11 +314,13 @@ class cachestore_file extends cache_store implements cache_is_key_aware, cache_i
             return $this->path . '/' . $key . '.cache';
         } else {
             // We are using a single subdirectory to achieve 1 level.
-            $subdir = substr($key, 0, 3);
+           // We suffix the subdir so it does not clash with any windows
+           // reserved filenames like 'con'.
+            $subdir = substr($key, 0, 3) . '-cache';
             $dir = $this->path . '/' . $subdir;
             if ($create) {
                 // Create the directory. This function does it recursivily!
-                make_writable_directory($dir);
+                make_writable_directory($dir, false);
             }
             return $dir . '/' . $key . '.cache';
         }
index 5121875..1388004 100644 (file)
@@ -119,6 +119,23 @@ class cache_phpunit_tests extends advanced_testcase {
         }
     }
 
+    /**
+     * Tests for cache keys that would break on windows.
+     */
+    public function test_windows_nasty_keys() {
+        $instance = cache_config_phpunittest::instance();
+        $instance->phpunit_add_definition('phpunit/windowskeytest', array(
+            'mode' => cache_store::MODE_APPLICATION,
+            'component' => 'phpunit',
+            'area' => 'windowskeytest',
+            'simplekeys' => true,
+            'simpledata' => true
+        ));
+        $cache = cache::make('phpunit', 'windowskeytest');
+        $this->assertTrue($cache->set('contest', 'test data 1'));
+        $this->assertEquals('test data 1', $cache->get('contest'));
+    }
+
     /**
      * Tests the default application cache
      */
@@ -191,9 +208,9 @@ class cache_phpunit_tests extends advanced_testcase {
      * @param cache_loader $cache
      */
     protected function run_on_cache(cache_loader $cache) {
-        $key = 'testkey';
+        $key = 'contestkey';
         $datascalars = array('test data', null);
-        $dataarray = array('test' => 'data', 'part' => 'two');
+        $dataarray = array('contest' => 'data', 'part' => 'two');
         $dataobject = (object)$dataarray;
 
         foreach ($datascalars as $datascalar) {
@@ -850,7 +867,7 @@ class cache_phpunit_tests extends advanced_testcase {
         // OK data added, data invalidated, and invalidation time has been set.
         // Now we need to manually add back the data and adjust the invalidation time.
         $hash = md5(cache_store::MODE_APPLICATION.'/phpunit/eventinvalidationtest/'.$CFG->wwwroot.'phpunit');
-        $timefile = $CFG->dataroot."/cache/cachestore_file/default_application/phpunit_eventinvalidationtest/las/lastinvalidation-$hash.cache";
+        $timefile = $CFG->dataroot."/cache/cachestore_file/default_application/phpunit_eventinvalidationtest/las-cache/lastinvalidation-$hash.cache";
         // Make sure the file is correct.
         $this->assertTrue(file_exists($timefile));
         $timecont = serialize(cache::now() - 60); // Back 60sec in the past to force it to re-invalidate.
@@ -858,7 +875,7 @@ class cache_phpunit_tests extends advanced_testcase {
         file_put_contents($timefile, $timecont);
         $this->assertTrue(file_exists($timefile));
 
-        $datafile = $CFG->dataroot."/cache/cachestore_file/default_application/phpunit_eventinvalidationtest/tes/testkey1-$hash.cache";
+        $datafile = $CFG->dataroot."/cache/cachestore_file/default_application/phpunit_eventinvalidationtest/tes-cache/testkey1-$hash.cache";
         $datacont = serialize("test data 1");
         make_writable_directory(dirname($datafile));
         file_put_contents($datafile, $datacont);
index c5920ff..3526c58 100644 (file)
@@ -365,7 +365,8 @@ class grade_report_user extends grade_report {
                     $cm = $instances[$grade_object->iteminstance];
                     if (!$cm->uservisible) {
                         // Further checks are required to determine whether the activity is entirely hidden or just greyed out.
-                        if ($cm->is_user_access_restricted_by_group() || $cm->is_user_access_restricted_by_conditional_access()) {
+                        if ($cm->is_user_access_restricted_by_group() || $cm->is_user_access_restricted_by_conditional_access() ||
+                                $cm->is_user_access_restricted_by_capability()) {
                             $hide = true;
                         }
                     }
index d6a3c2a..98c4c55 100644 (file)
@@ -554,7 +554,6 @@ $string['gdrequired'] = 'The GD extension is now required by Moodle for image co
 $string['generalsettings'] = 'General settings';
 $string['geoipfile'] = 'GeoIP city data file';
 $string['getremoteaddrconf'] = 'Logged IP address source';
-$string['globalsquoteswarning'] = '<p><strong>Security Warning</strong>: to operate properly, Moodle requires <br />that you make certain changes to your current PHP settings.<p/><p>You <em>must</em> set <code>register_globals=off</code> and/or <code>magic_quotes_gpc=on</code>. <br />If possible, you should set <code>register_globals=off</code> to improve general <br /> server security, setting <code>magic_quotes_gpc=on</code> is also recommended.<p/><p>These settings are controlled by editing your <code>php.ini</code>, Apache/IIS <br />configuration or <code>.htaccess</code> file.</p>';
 $string['globalswarning'] = '<p><strong>SECURITY WARNING!</strong></p><p> To operate properly, Moodle requires <br />that you make certain changes to your current PHP settings.</p><p>You <em>must</em> set <code>register_globals=off</code>.</p><p>This setting is controlled by editing your <code>php.ini</code>, Apache/IIS <br />configuration or <code>.htaccess</code> file.</p>';
 $string['groupenrolmentkeypolicy'] = 'Group enrolment key policy';
 $string['groupenrolmentkeypolicy_desc'] = 'Turning this on will make Moodle check group enrolment keys against a valid password policy.';
index 0be294d..3b52fc0 100644 (file)
@@ -57,98 +57,11 @@ $string['configurationcomplete'] = 'Configuration completed';
 $string['configurationcompletehead'] = 'Configuration completed';
 $string['configurationcompletesub'] = 'Moodle made an attempt to save your configuration in a file in the root of your Moodle installation.';
 $string['database'] = 'Database';
-$string['databasecreationsettings'] = 'Now you need to configure the database settings where most Moodle data
-    will be stored.  This database will be created automatically by the installer
-    with the settings specified below.<br />
-    <br /> <br />
-       <b>Type:</b> fixed to "mysql" by the installer<br />
-       <b>Host:</b> fixed to "localhost" by the installer<br />
-       <b>Name:</b> database name, eg moodle<br />
-       <b>User:</b> fixed to "root" by the installer<br />
-       <b>Password:</b> your database password<br />
-       <b>Tables Prefix:</b> optional prefix to use for all table names';
-$string['databasecreationsettingshead'] = 'Now you need to configure the database settings where most Moodle data
-    will be stored.  This database will be created automatically by the installer
-    with the settings specified below.';
-$string['databasecreationsettingssub'] = '<b>Type:</b> fixed to "mysql" by the installer<br />
-       <b>Host:</b> fixed to "localhost" by the installer<br />
-       <b>Name:</b> database name, eg moodle<br />
-       <b>User:</b> fixed to "root" by the installer<br />
-       <b>Password:</b> your database password<br />
-       <b>Tables Prefix:</b> optional prefix to use for all table names';
-$string['databasecreationsettingssub2'] = '<b>Type:</b> fixed to "mysqli" by the installer<br />
-       <b>Host:</b> fixed to "localhost" by the installer<br />
-       <b>Name:</b> database name, eg moodle<br />
-       <b>User:</b> fixed to "root" by the installer<br />
-       <b>Password:</b> your database password<br />
-       <b>Tables Prefix:</b> optional prefix to use for all table names';
 $string['databasehead'] = 'Database settings';
 $string['databasehost'] = 'Database host';
 $string['databasename'] = 'Database name';
 $string['databasepass'] = 'Database password';
 $string['databaseport'] = 'Database port';
-$string['databasesettings'] = 'Now you need to configure the database where most Moodle data
-    will be stored.  This database must already have been created
-    and a username and password created to access it.<br />
-    <br /> <br />
-       <b>Type:</b> mysql or postgres7<br />
-       <b>Host:</b> eg localhost or db.isp.com<br />
-       <b>Name:</b> database name, eg moodle<br />
-       <b>User:</b> your database username<br />
-       <b>Password:</b> your database password<br />
-       <b>Tables Prefix:</b> optional prefix to use for all table names';
-$string['databasesettingshead'] = 'Now you need to configure the database where most Moodle data
-    will be stored.  This database must already have been created
-    and a username and password created to access it.';
-$string['databasesettingssub'] = '<b>Type:</b> mysql or postgres7<br />
-       <b>Host:</b> eg localhost or db.isp.com<br />
-       <b>Name:</b> database name, eg moodle<br />
-       <b>User:</b> your database username<br />
-       <b>Password:</b> your database password<br />
-       <b>Tables Prefix:</b> optional prefix to use for all table names';
-$string['databasesettingssub_mssql'] = '<b>Type:</b> SQL*Server (non UTF-8) <b><strong  class="errormsg">Experimental! (not for use in production)</strong></b><br />
-       <b>Host:</b> eg localhost or db.isp.com<br />
-       <b>Name:</b> database name, eg moodle<br />
-       <b>User:</b> your database username<br />
-       <b>Password:</b> your database password<br />
-       <b>Tables Prefix:</b> prefix to use for all table names (mandatory)';
-$string['databasesettingssub_mssql_n'] = '<b>Type:</b> SQL*Server (UTF-8 enabled)<br />
-       <b>Host:</b> eg localhost or db.isp.com<br />
-       <b>Name:</b> database name, eg moodle<br />
-       <b>User:</b> your database username<br />
-       <b>Password:</b> your database password<br />
-       <b>Tables Prefix:</b> prefix to use for all table names (mandatory)';
-$string['databasesettingssub_mysql'] = '<b>Type:</b> MySQL<br />
-       <b>Host:</b> eg localhost or db.isp.com<br />
-       <b>Name:</b> database name, eg moodle<br />
-       <b>User:</b> your database username<br />
-       <b>Password:</b> your database password<br />
-       <b>Tables Prefix:</b> prefix to use for all table names (optional)';
-$string['databasesettingssub_mysqli'] = '<b>Type:</b> Improved MySQL<br />
-       <b>Host:</b> eg localhost or db.isp.com<br />
-       <b>Name:</b> database name, eg moodle<br />
-       <b>User:</b> your database username<br />
-       <b>Password:</b> your database password<br />
-       <b>Tables Prefix:</b> prefix to use for all table names (optional)';
-$string['databasesettingssub_oci8po'] = '<b>Type:</b> Oracle<br />
-       <b>Host:</b> not used, must be left blank<br />
-       <b>Name:</b> given name of the tnsnames.ora connection<br />
-       <b>User:</b> your database username<br />
-       <b>Password:</b> your database password<br />
-       <b>Tables Prefix:</b> prefix to use for all table names (mandatory, 2cc. max)';
-$string['databasesettingssub_odbc_mssql'] = '<b>Type:</b> SQL*Server (over ODBC) <b><strong  class="errormsg">Experimental! (not for use in production)</strong></b><br />
-       <b>Host:</b> given name of the DSN in the ODBC control panel<br />
-       <b>Name:</b> database name, eg moodle<br />
-       <b>User:</b> your database username<br />
-       <b>Password:</b> your database password<br />
-       <b>Tables Prefix:</b> prefix to use for all table names (mandatory)';
-$string['databasesettingssub_postgres7'] = '<b>Type:</b> PostgreSQL<br />
-       <b>Host:</b> eg localhost or db.isp.com<br />
-       <b>Name:</b> database name, eg moodle<br />
-       <b>User:</b> your database username<br />
-       <b>Password:</b> your database password<br />
-       <b>Tables Prefix:</b> prefix to use for all table names (mandatory)';
-$string['databasesettingswillbecreated'] = '<b>Note:</b> The installer will try to create the database automatically if not exists.';
 $string['databasesocket'] = 'Unix socket';
 $string['databasetypehead'] = 'Choose database driver';
 $string['databasetypesub'] = 'Moodle supports several types of database servers. Please contact server administrator if you do not know which type to use.';
@@ -164,10 +77,6 @@ $string['dbpass'] = 'Password';
 $string['dbport'] = 'Port';
 $string['dbprefix'] = 'Tables prefix';
 $string['dbtype'] = 'Type';
-$string['dbwrongencoding'] = 'The selected database is running under one non-recommended encoding ({$a}). It would be better to use one Unicode (UTF-8) encoded database instead. Anyway, you can bypass this test by selecting the "Skip DB Encoding Test" check below, but you could experience problems in the future.';
-$string['dbwronghostserver'] = 'You must follow "Host" rules as explained above.';
-$string['dbwrongnlslang'] = 'The NLS_LANG environment variable in your web server must use the AL32UTF8 charset. See PHP documentation about how to configure OCI8 properly.';
-$string['dbwrongprefix'] = 'You must follow "Tables Prefix" rules as explained above.';
 $string['directorysettings'] = '<p>Please confirm the locations of this Moodle installation.</p>
 
 <p><b>Web address:</b>
@@ -227,16 +136,6 @@ $string['fileuploadshelp'] = '<p>File uploading seems to be disabled on your ser
 <p>To enable file uploading you (or your system administrator) will need to 
    edit the main php.ini file on your system and change the setting for 
    <b>file_uploads</b> to \'1\'.</p>';
-$string['globalsquotes'] = 'Insecure handling of globals';
-$string['globalsquoteserror'] = 'Fix your PHP settings: disable register_globals and/or enable magic_quotes_gpc';
-$string['globalsquoteshelp'] = '<p>Combination of disabled magic quotes GPC and enabled register globals both at the same time is not recommended.</p>
-
-<p>The recommended setting is <b>magic_quotes_gpc = On</b> and <b>register_globals = Off</b> in your php.ini</p>
-
-<p>If you don\'t have access to your php.ini, you might be able to place the following line in a file
-   called .htaccess within your Moodle directory:</p>
-   <blockquote><div>php_value magic_quotes_gpc On</div></blockquote>
-   <blockquote><div>php_value register_globals Off</div></blockquote>';
 $string['chooselanguage'] = 'Choose a language';
 $string['chooselanguagehead'] = 'Choose a language';
 $string['chooselanguagesub'] = 'Please choose a language for the installation. This language will also be used as the default language for the site, though it may be changed later.';
@@ -276,12 +175,7 @@ $string['memorylimithelp'] = '<p>The PHP memory limit for your server is current
     <p>However, on some servers this will prevent <b>all</b> PHP pages from working 
     (you will see errors when you look at pages) so you\'ll have to remove the .htaccess file.</p></li>
 </ol>';
-$string['mssql'] = 'SQL*Server (mssql)';
 $string['mssqlextensionisnotpresentinphp'] = 'PHP has not been properly configured with the MSSQL extension so that it can communicate with SQL*Server.  Please check your php.ini file or recompile PHP.';
-$string['mssql_n'] = 'SQL*Server with UTF-8 support (mssql_n)';
-$string['mysql'] = 'MySQL (mysql)';
-$string['mysqlextensionisnotpresentinphp'] = 'PHP has not been properly configured with the MySQL extension so that it can communicate with MySQL.  Please check your php.ini file or recompile PHP.';
-$string['mysqli'] = 'Improved MySQL (mysqli)';
 $string['mysqliextensionisnotpresentinphp'] = 'PHP has not been properly configured with the MySQLi extension so that it can communicate with MySQL.  Please check your php.ini file or recompile PHP.  MySQLi extension is not available for PHP 4.';
 $string['nativemariadb'] = 'MariaDB (native/mariadb)';
 $string['nativemariadbhelp'] = 'Now you need to configure the database where most Moodle data will be stored.
@@ -299,10 +193,12 @@ This database must already have been created and a username and password created
 $string['nativepgsql'] = 'PostgreSQL (native/pgsql)';
 $string['nativepgsqlhelp'] = 'Now you need to configure the database where most Moodle data will be stored.
 This database must already have been created and a username and password created to access it. Table prefix is mandatory.';
+$string['nativesqlsrv'] = 'SQL*Server Microsoft (native/sqlsrv)';
+$string['nativesqlsrvhelp'] = 'Now you need to configure the database where most Moodle data will be stored.
+This database must already have been created and a username and password created to access it. Table prefix is mandatory.';
+$string['nativesqlsrvnodriver'] = 'Microsoft Drivers for SQL Server for PHP are not installed or not configured properly.';
+$string['nativesqlsrvnonwindows'] = 'Microsoft Drivers for SQL Server for PHP are available only for Windows OS.';
 $string['ociextensionisnotpresentinphp'] = 'PHP has not been properly configured with the OCI8 extension so that it can communicate with Oracle.  Please check your php.ini file or recompile PHP.';
-$string['oci8po'] = 'Oracle (oci8po)';
-$string['odbcextensionisnotpresentinphp'] = 'PHP has not been properly configured with the ODBC extension so that it can communicate with SQL*Server.  Please check your php.ini file or recompile PHP.';
-$string['odbc_mssql'] = 'SQL*Server over ODBC (odbc_mssql)';
 $string['pass'] = 'Pass';
 $string['paths'] = 'Paths';
 $string['pathserrcreatedataroot'] = 'Data directory ({$a->dataroot}) cannot be created by the installer.';
@@ -329,7 +225,6 @@ $string['phpversionhelp'] = '<p>Moodle requires a PHP version of at least 4.3.0
 <p>You are currently running version {$a}</p>
 <p>You must upgrade PHP or move to a host with a newer version of PHP!<br />
 (In case of 5.0.x you could also downgrade to 4.4.x version)</p>';
-$string['postgres7'] = 'PostgreSQL (postgres7)';
 $string['releasenoteslink'] = 'For information about this version of Moodle, please see the release notes at {$a}';
 $string['safemode'] = 'Safe mode';
 $string['safemodeerror'] = 'Moodle may have trouble with safe mode on';
@@ -345,12 +240,6 @@ $string['sessionautostarterror'] = 'This should be off';
 $string['sessionautostarthelp'] = '<p>Moodle requires session support and will not function without it.</p>
 
 <p>Sessions can be enabled in the php.ini file ... look for the session.auto_start parameter.</p>';
-$string['skipdbencodingtest'] = 'Skip DB encoding test';
-$string['nativesqlsrv'] = 'SQL*Server Microsoft (native/sqlsrv)';
-$string['nativesqlsrvhelp'] = 'Now you need to configure the database where most Moodle data will be stored.
-This database must already have been created and a username and password created to access it. Table prefix is mandatory.';
-$string['nativesqlsrvnodriver'] = 'Microsoft Drivers for SQL Server for PHP are not installed or not configured properly.';
-$string['nativesqlsrvnonwindows'] = 'Microsoft Drivers for SQL Server for PHP are available only for Windows OS.';
 $string['sqliteextensionisnotpresentinphp'] = 'PHP has not been properly configured with the SQLite extension.  Please check your php.ini file or recompile PHP.';
 $string['upgradingqtypeplugin'] = 'Upgrading question/type plugin';
 $string['welcomep10'] = '{$a->installername} ({$a->installerversion})';
index a580d0a..ee19a96 100644 (file)
@@ -2306,5 +2306,12 @@ function xmldb_main_upgrade($oldversion) {
         upgrade_main_savepoint(true, 2013071500.02);
     }
 
+    if ($oldversion < 2013072600.01) {
+        upgrade_mssql_nvarcharmax();
+        upgrade_mssql_varbinarymax();
+
+        upgrade_main_savepoint(true, 2013072600.01);
+    }
+
     return true;
 }
index 6edc5d8..3d89eb9 100644 (file)
@@ -164,3 +164,109 @@ function upgrade_mysql_fix_unsigned_and_lob_columns() {
         $pbar->update($i, $tablecount, "Converted unsigned/lob columns in MySQL database - $i/$tablecount.");
     }
 }
+
+/**
+ * Migrate NTEXT to NVARCHAR(MAX).
+ */
+function upgrade_mssql_nvarcharmax() {
+    global $DB;
+
+    if ($DB->get_dbfamily() !== 'mssql') {
+        return;
+    }
+
+    $pbar = new progress_bar('mssqlconvertntext', 500, true);
+
+    $prefix = $DB->get_prefix();
+    $tables = $DB->get_tables(false);
+
+    $tablecount = count($tables);
+    $i = 0;
+    foreach ($tables as $table) {
+        $i++;
+
+        $columns = array();
+
+        $sql = "SELECT column_name
+                  FROM INFORMATION_SCHEMA.COLUMNS
+                 WHERE table_name = '{{$table}}' AND UPPER(data_type) = 'NTEXT'";
+        $rs = $DB->get_recordset_sql($sql);
+        foreach ($rs as $column) {
+            $columns[] = $column->column_name;
+        }
+        $rs->close();
+
+        if ($columns) {
+            // Set appropriate timeout - 1 minute per thousand of records should be enough, min 60 minutes just in case.
+            $count = $DB->count_records($table, array());
+            $timeout = ($count/1000)*60;
+            $timeout = ($timeout < 60*60) ? 60*60 : (int)$timeout;
+            upgrade_set_timeout($timeout);
+
+            $updates = array();
+            foreach ($columns as $column) {
+                // Change the definition.
+                $sql = "ALTER TABLE {$prefix}$table ALTER COLUMN $column NVARCHAR(MAX)";
+                $DB->change_database_structure($sql);
+                $updates[] = "$column = $column";
+            }
+
+            // Now force the migration of text data to new optimised storage.
+            $sql = "UPDATE {{$table}} SET ".implode(', ', $updates);
+            $DB->execute($sql);
+        }
+
+        $pbar->update($i, $tablecount, "Converted NTEXT to NVARCHAR(MAX) columns in MS SQL Server database - $i/$tablecount.");
+    }
+}
+
+/**
+ * Migrate IMAGE to VARBINARY(MAX).
+ */
+function upgrade_mssql_varbinarymax() {
+    global $DB;
+
+    if ($DB->get_dbfamily() !== 'mssql') {
+        return;
+    }
+
+    $pbar = new progress_bar('mssqlconvertimage', 500, true);
+
+    $prefix = $DB->get_prefix();
+    $tables = $DB->get_tables(false);
+
+    $tablecount = count($tables);
+    $i = 0;
+    foreach ($tables as $table) {
+        $i++;
+
+        $columns = array();
+
+        $sql = "SELECT column_name
+                  FROM INFORMATION_SCHEMA.COLUMNS
+                 WHERE table_name = '{{$table}}' AND UPPER(data_type) = 'IMAGE'";
+        $rs = $DB->get_recordset_sql($sql);
+        foreach ($rs as $column) {
+            $columns[] = $column->column_name;
+        }
+        $rs->close();
+
+        if ($columns) {
+            // Set appropriate timeout - 1 minute per thousand of records should be enough, min 60 minutes just in case.
+            $count = $DB->count_records($table, array());
+            $timeout = ($count/1000)*60;
+            $timeout = ($timeout < 60*60) ? 60*60 : (int)$timeout;
+            upgrade_set_timeout($timeout);
+
+            foreach ($columns as $column) {
+                // Change the definition.
+                $sql = "ALTER TABLE {$prefix}$table ALTER COLUMN $column VARBINARY(MAX)";
+                $DB->change_database_structure($sql);
+            }
+
+            // Binary columns should not be used, do not waste time optimising the storage.
+        }
+
+        $pbar->update($i, $tablecount, "Converted IMAGE to VARBINARY(MAX) columns in MS SQL Server database - $i/$tablecount.");
+    }
+}
index bbf769d..ccd2d81 100644 (file)
@@ -221,10 +221,10 @@ class mssql_sql_generator extends sql_generator {
                 $dbtype .= '(' . $xmldb_length . ')';
                 break;
             case XMLDB_TYPE_TEXT:
-                $dbtype = 'NTEXT';
+                $dbtype = 'NVARCHAR(MAX)';
                 break;
             case XMLDB_TYPE_BINARY:
-                $dbtype = 'IMAGE';
+                $dbtype = 'VARBINARY(MAX)';
                 break;
             case XMLDB_TYPE_DATETIME:
                 $dbtype = 'DATETIME';
index d8703d2..c9ab87c 100644 (file)
@@ -231,9 +231,13 @@ abstract class moodle_database {
     /**
      * Returns the localised database description
      * Note: can be used before connect()
+     * @deprecated since 2.6
      * @return string
      */
-    public abstract function get_configuration_hints();
+    public function get_configuration_hints() {
+        debugging('$DB->get_configuration_hints() method is deprecated, use $DB->get_configuration_help() instead');
+        return $this->get_configuration_help();
+    }
 
     /**
      * Returns the db related part of config.php
index 4ac7472..2191b89 100644 (file)
@@ -98,21 +98,6 @@ class mssql_native_moodle_database extends moodle_database {
         return get_string('nativemssqlhelp', 'install');
     }
 
-    /**
-     * Returns localised database description
-     * Note: can be used before connect()
-     * @return string
-     */
-    public function get_configuration_hints() {
-        $str = get_string('databasesettingssub_mssql', 'install');
-        $str .= "<p style='text-align:right'><a href=\"javascript:void(0)\" ";
-        $str .= "onclick=\"return window.open('http://docs.moodle.org/en/Installing_MSSQL_for_PHP')\"";
-        $str .= ">";
-        $str .= '<img src="pix/docs.gif' . '" alt="Docs" class="iconhelp" />';
-        $str .= get_string('moodledocslink', 'install') . '</a></p>';
-        return $str;
-    }
-
     /**
      * Connect to db
      * Must be called before other methods.
@@ -479,9 +464,15 @@ class mssql_native_moodle_database extends moodle_database {
             // id columns being auto_incremnt are PK by definition
             $info->primary_key = ($info->name == 'id' && $info->meta_type == 'R' && $info->auto_increment);
 
-            // Put correct length for character and LOB types
-            $info->max_length = $info->meta_type == 'C' ? $rawcolumn->char_max_length : $rawcolumn->max_length;
-            $info->max_length = ($info->meta_type == 'X' || $info->meta_type == 'B') ? -1 : $info->max_length;
+            if ($info->meta_type === 'C' and $rawcolumn->char_max_length == -1) {
+                // This is NVARCHAR(MAX), not a normal NVARCHAR.
+                $info->max_length = -1;
+                $info->meta_type = 'X';
+            } else {
+                // Put correct length for character and LOB types
+                $info->max_length = $info->meta_type == 'C' ? $rawcolumn->char_max_length : $rawcolumn->max_length;
+                $info->max_length = ($info->meta_type == 'X' || $info->meta_type == 'B') ? -1 : $info->max_length;
+            }
 
             // Scale
             $info->scale = $rawcolumn->scale ? $rawcolumn->scale : false;
@@ -588,6 +579,7 @@ class mssql_native_moodle_database extends moodle_database {
                 $type = 'X';
                 break;
             case 'IMAGE':
+            case 'VARBINARY':
             case 'VARBINARY(MAX)':
                 $type = 'B';
                 break;
index 9d06809..7a2d31f 100644 (file)
@@ -297,15 +297,6 @@ class mysqli_native_moodle_database extends moodle_database {
         return get_string('nativemysqlihelp', 'install');
     }
 
-    /**
-     * Returns localised database description
-     * Note: can be used before connect()
-     * @return string
-     */
-    public function get_configuration_hints() {
-        return get_string('databasesettingssub_mysqli', 'install');
-    }
-
     /**
      * Diagnose database and tables, this function is used
      * to verify database and driver settings, db engine types, etc.
index f146088..10906b8 100644 (file)
@@ -109,15 +109,6 @@ class oci_native_moodle_database extends moodle_database {
         return get_string('nativeocihelp', 'install');
     }
 
-    /**
-     * Returns localised database description
-     * Note: can be used before connect()
-     * @return string
-     */
-    public function get_configuration_hints() {
-        return get_string('databasesettingssub_oci', 'install');
-    }
-
     /**
      * Diagnose database and tables, this function is used
      * to verify database and driver settings, db engine types, etc.
index 61b161c..cc7b3bb 100644 (file)
@@ -128,15 +128,6 @@ abstract class pdo_moodle_database extends moodle_database {
         return get_string('pdo'.$this->get_dbtype().'help', 'install');
     }
 
-    /**
-     * Returns localised database description
-     * Note: can be used before connect()
-     * @return string
-     */
-    public function get_configuration_hints() {
-        return get_string('databasesettingssub_' . $this->get_dbtype() . '_pdo', 'install');
-    }
-
     /**
      * Returns database server info array
      * @return array Array containing 'description' and 'version' info
index 5783972..7c9792e 100644 (file)
@@ -102,15 +102,6 @@ class pgsql_native_moodle_database extends moodle_database {
         return get_string('nativepgsqlhelp', 'install');
     }
 
-    /**
-     * Returns localised database description
-     * Note: can be used before connect()
-     * @return string
-     */
-    public function get_configuration_hints() {
-        return get_string('databasesettingssub_postgres7', 'install');
-    }
-
     /**
      * Connect to db
      * Must be called before other methods.
index af3697b..b5062b1 100644 (file)
@@ -117,21 +117,6 @@ class sqlsrv_native_moodle_database extends moodle_database {
         return get_string('nativesqlsrvhelp', 'install');
     }
 
-    /**
-     * Returns localised database description
-     * Note: can be used before connect()
-     * @return string
-     */
-    public function get_configuration_hints() {
-        $str = get_string('databasesettingssub_sqlsrv', 'install');
-        $str .= "<p style='text-align:right'><a href=\"javascript:void(0)\" ";
-        $str .= "onclick=\"return window.open('http://docs.moodle.org/en/Using_the_Microsoft_SQL_Server_Driver_for_PHP')\"";
-        $str .= ">";
-        $str .= '<img src="pix/docs.gif'.'" alt="Docs" class="iconhelp" />';
-        $str .= get_string('moodledocslink', 'install').'</a></p>';
-        return $str;
-    }
-
     /**
      * Connect to db
      * Must be called before most other methods. (you can call methods that return connection configuration parameters)
@@ -543,9 +528,15 @@ class sqlsrv_native_moodle_database extends moodle_database {
             // id columns being auto_incremnt are PK by definition
             $info->primary_key = ($info->name == 'id' && $info->meta_type == 'R' && $info->auto_increment);
 
-            // Put correct length for character and LOB types
-            $info->max_length = $info->meta_type == 'C' ? $rawcolumn->char_max_length : $rawcolumn->max_length;
-            $info->max_length = ($info->meta_type == 'X' || $info->meta_type == 'B') ? -1 : $info->max_length;
+            if ($info->meta_type === 'C' and $rawcolumn->char_max_length == -1) {
+                // This is NVARCHAR(MAX), not a normal NVARCHAR.
+                $info->max_length = -1;
+                $info->meta_type = 'X';
+            } else {
+                // Put correct length for character and LOB types
+                $info->max_length = $info->meta_type == 'C' ? $rawcolumn->char_max_length : $rawcolumn->max_length;
+                $info->max_length = ($info->meta_type == 'X' || $info->meta_type == 'B') ? -1 : $info->max_length;
+            }
 
             // Scale
             $info->scale = $rawcolumn->scale ? $rawcolumn->scale : false;
@@ -660,6 +651,7 @@ class sqlsrv_native_moodle_database extends moodle_database {
            break;
 
           case 'IMAGE':
+          case 'VARBINARY':
           case 'VARBINARY(MAX)':
            $type = 'B';
            break;
index 5f0fbde..273dcff 100644 (file)
@@ -4948,7 +4948,6 @@ class moodle_database_for_testing extends moodle_database {
     protected function get_dblibrary(){}
     public function get_name(){}
     public function get_configuration_help(){}
-    public function get_configuration_hints(){}
     public function connect($dbhost, $dbuser, $dbpass, $dbname, $prefix, array $dboptions=null){}
     public function get_server_info(){}
     protected function allowed_param_types(){}
index 1355b08..ac79c12 100644 (file)
@@ -1203,7 +1203,8 @@ class cm_info extends stdClass {
         }
 
         // Check group membership.
-        if ($this->is_user_access_restricted_by_group()) {
+        if ($this->is_user_access_restricted_by_group() ||
+                $this->is_user_access_restricted_by_capability()) {
 
              $this->uservisible = false;
             // Ensure activity is completely hidden from the user.
@@ -1234,6 +1235,23 @@ class cm_info extends stdClass {
         return false;
     }
 
+    /**
+     * Checks whether mod/...:view capability restricts the current user's access.
+     *
+     * @return bool True if the user access is restricted.
+     */
+    public function is_user_access_restricted_by_capability() {
+        $capability = 'mod/' . $this->modname . ':view';
+        $capabilityinfo = get_capability_info($capability);
+        if (!$capabilityinfo) {
+            // Capability does not exist, no one is prevented from seeing the activity.
+            return false;
+        }
+
+        // You are blocked if you don't have the capability.
+        return !has_capability($capability, context_module::instance($this->id));
+    }
+
     /**
      * Checks whether the module's conditional access settings mean that the user cannot see the activity at all
      *
index 49551c0..25e2de2 100644 (file)
@@ -1657,6 +1657,7 @@ class YUI_config {
         $cache = cache::make('core', 'yuimodules');
         if (!isset($CFG->jsrev) || $CFG->jsrev == -1) {
             $metadata = array();
+            $metadata = $this->get_moodle_metadata();
             $cache->delete('metadata');
         } else {
             // Attempt to get the metadata from the cache.
index e08d3c4..7b7e335 100644 (file)
@@ -1260,10 +1260,15 @@ function make_writable_directory($dir, $exceptiononerror = true) {
 
     if (!file_exists($dir)) {
         if (!mkdir($dir, $CFG->directorypermissions, true)) {
-            if ($exceptiononerror) {
-                throw new invalid_dataroot_permissions($dir.' can not be created, check permissions.');
-            } else {
-                return false;
+            clearstatcache();
+            // There might be a race condition when creating directory.
+            if (!is_dir($dir)) {
+                if ($exceptiononerror) {
+                    throw new invalid_dataroot_permissions($dir.' can not be created, check permissions.');
+                } else {
+                    debugging('Can not create directory: '.$dir, DEBUG_DEVELOPER);
+                    return false;
+                }
             }
         }
     }
index d0a4192..d2591e2 100644 (file)
@@ -11,6 +11,8 @@ information provided here is intended especially for developers.
 * Use core_text::* instead of textlib:: and also core_collator::* instead of collatorlib::*.
 * Use new function moodleform::mock_submit() to simulate form submission in unit tests (backported).
 * New $CFG->localcachedir setting useful for cluster nodes. Admins have to update X-Sendfile aliases if used.
+* MS SQL Server drivers are now using NVARCHAR(MAX) instead of NTEXT and VARBINARY(MAX) instead of IMAGE,
+  this change should be fully transparent and it should help significantly with add-on compatibility.
 
 DEPRECATIONS:
 Various previously deprecated functions have now been altered to throw DEBUG_DEVELOPER debugging notices
index b168b20..7c29a61 100644 (file)
@@ -279,7 +279,8 @@ class mod_assign_external extends external_api {
         $extrafields='m.id as assignmentid, m.course, m.nosubmissions, m.submissiondrafts, m.sendnotifications, '.
                      'm.sendlatenotifications, m.duedate, m.allowsubmissionsfromdate, m.grade, m.timemodified, '.
                      'm.completionsubmit, m.cutoffdate, m.teamsubmission, m.requireallteammemberssubmit, '.
-                     'm.teamsubmissiongroupingid, m.blindmarking, m.revealidentities, m.requiresubmissionstatement';
+                     'm.teamsubmissiongroupingid, m.blindmarking, m.revealidentities, m.attemptreopenmethod, '.
+                     'm.maxattempts, m.markingworkflow, m.markingallocation, m.requiresubmissionstatement';
         $coursearray = array();
         foreach ($courses as $id => $course) {
             $assignmentarray = array();
@@ -333,6 +334,10 @@ class mod_assign_external extends external_api {
                         'teamsubmissiongroupingid' => $module->teamsubmissiongroupingid,
                         'blindmarking' => $module->blindmarking,
                         'revealidentities' => $module->revealidentities,
+                        'attemptreopenmethod' => $module->attemptreopenmethod,
+                        'maxattempts' => $module->maxattempts,
+                        'markingworkflow' => $module->markingworkflow,
+                        'markingallocation' => $module->markingallocation,
                         'requiresubmissionstatement' => $module->requiresubmissionstatement,
                         'configs' => $configarray
                     );
@@ -364,6 +369,7 @@ class mod_assign_external extends external_api {
         return new external_single_structure(
             array(
                 'id' => new external_value(PARAM_INT, 'assignment id'),
+                'cmid' => new external_value(PARAM_INT, 'course module id'),
                 'course' => new external_value(PARAM_INT, 'course id'),
                 'name' => new external_value(PARAM_TEXT, 'assignment name'),
                 'nosubmissions' => new external_value(PARAM_INT, 'no submissions'),
@@ -381,6 +387,10 @@ class mod_assign_external extends external_api {
                 'teamsubmissiongroupingid' => new external_value(PARAM_INT, 'the grouping id for the team submission groups'),
                 'blindmarking' => new external_value(PARAM_INT, 'if enabled, hide identities until reveal identities actioned'),
                 'revealidentities' => new external_value(PARAM_INT, 'show identities for a blind marking assignment'),
+                'attemptreopenmethod' => new external_value(PARAM_TEXT, 'method used to control opening new attempts'),
+                'maxattempts' => new external_value(PARAM_INT, 'maximum number of attempts allowed'),
+                'markingworkflow' => new external_value(PARAM_INT, 'enable marking workflow'),
+                'markingallocation' => new external_value(PARAM_INT, 'enable marking allocation'),
                 'requiresubmissionstatement' => new external_value(PARAM_INT, 'student must accept submission statement'),
                 'configs' => new external_multiple_structure(self::get_assignments_config_structure(), 'configuration settings')
             ), 'assignment information object');
index 814e3c9..82ea132 100644 (file)
@@ -3595,7 +3595,7 @@ function assignment_get_all_submissions($assignment, $sort="", $dir="DESC") {
  * Given a course_module object, this function returns any "extra" information that may be needed
  * when printing this activity in a course listing.  See get_array_of_activities() in course/lib.php.
  *
- * @param $coursemodule object The coursemodule object (record).
+ * @param stdClass $coursemodule object The coursemodule object (record).
  * @return cached_cm_info An object on information that the courses will know about (most noticeably, an icon).
  */
 function assignment_get_coursemodule_info($coursemodule) {
index 053df31..11c4d21 100644 (file)
@@ -37,15 +37,11 @@ M.mod_chat_ajax.init = function(Y, cfg) {
         init : function(cfg) {
             this.cfg = cfg;
             this.cfg.req_count = this.cfg.req_count || 0;
-            participantswidth = 180;
-            if (Y.one('#input-message').get('docWidth') < 640) {
-                participantswidth = 120;
-            }
             this.layout = new Y.YUI2.widget.Layout({
                 units : [
-                     {position: 'right', width: participantswidth, resize: true, gutter: '1px', scroll: true, body: 'chat-userlist', animate: false},
-                     {position: 'bottom', height: 42, resize: false, body: 'chat-input-area', gutter: '1px', collapse: false, resize: false},
-                     {position: 'center', body: 'chat-messages', gutter: '0px', scroll: true}
+                     {position: 'right', width: 180, resize: true, gutter: '5px', scroll: true, body: 'chat-userlist', animate: false},
+                     {position: 'bottom', height: 42, resize: false, body: 'chat-input-area', gutter: '5px', collapse: false, resize: false},
+                     {position: 'center', body: 'chat-messages', gutter: '5px', scroll: true}
                 ]
             });
 
index 59a57af..141f62e 100644 (file)
@@ -1,14 +1,12 @@
-.yui-skin-sam .yui-layout .yui-layout-hd {border:0;}
-.yui-skin-sam .yui-layout .yui-layout-unit div.yui-layout-bd-nohd {border:0;}
-.yui-skin-sam .yui-layout .yui-layout-unit div.yui-layout-bd {border:0;}
-.yui-skin-sam .yui-layout .yui-layout-unit div.yui-layout-unit-right {background: white;}
-.yui-skin-sam .yui-layout-unit-bottom  {background: #F2F2F2;}
-.yui-skin-sam .yui-layout-unit-right {background: #eef2f8;}
-.yui-skin-sam .yui-layout-unit-center {background: white;}
-.yui-skin-sam .yui-layout-unit-top {background: #FFE39D;}
-.yui-skin-sam .yui-layout .yui-layout-unit div.yui-layout-bd {background: transparent;}
-
-#chat-messages {padding-top:15px;}
+.yui-skin-sam .yui-layout .yui-layout-hd { border:0; }
+.yui-skin-sam .yui-layout .yui-layout-unit div.yui-layout-bd-nohd { border:0; }
+.yui-skin-sam .yui-layout .yui-layout-unit div.yui-layout-bd { border:0; }
+.yui-skin-sam .yui-layout .yui-layout-unit div.yui-layout-unit-right { background: white; }
+.yui-skin-sam .yui-layout-unit-bottom  { background: #F2F2F2; }
+.yui-skin-sam .yui-layout-unit-right { background: #eef2f8; }
+.yui-skin-sam .yui-layout-unit-center { background: white; }
+.yui-skin-sam .yui-layout-unit-top { background: #FFE39D; }
+.yui-skin-sam .yui-layout .yui-layout-unit div.yui-layout-bd { background: transparent; }
 
 #input-message {background:#FFFFFF url(input.png) repeat-x scroll 0 0;padding:0 9px;border: 1px solid #999;border-radius: 9px;-moz-border-radius: 9px;}
 .mdl-chat-entry,
@@ -16,9 +14,7 @@
 .dir-rtl .mdl-chat-entry,
 .dir-rtl .mdl-chat-my-entry {height: 90px;}
 
-.mdl-chat-entry .chat-event {padding-bottom:15px;}
-
-.chat-message .chat-message-meta {padding-top:15px;padding-bottom:15px;}
+.chat-message .chat-message-meta {padding-top:15px;}
 .chat-message .picture {vertical-align:middle;}
 .chat-message .right {text-align:right;}
 .chat-message .left {text-align:left;}
@@ -31,9 +27,8 @@
 #chat-userlist {background: #E3E8F0;height: 100%;}
 
 /**
- * The following CSS is a cut down version of PURE CSS SPEECH BUBBLES.
- * Moodle only uses a small subset of the original.
- * The original version is available at http://nicolasgallagher.com/pure-css-speech-bubbles/
+ * The following CSS has been minified to reduce its size
+ * The original unminified version is available at http://nicolasgallagher.com/pure-css-speech-bubbles/
  */
 
 /* ------------------------------------------
@@ -50,100 +45,4 @@ Version: 1.2 (03 March 2011)
 Dual licensed under MIT and GNU GPLv2 © Nicolas Gallagher
 ------------------------------------------ */
 
-.triangle-border {
-    position:relative;
-    padding:15px;
-    margin:1em 0 3em;
-    border:5px solid #5a8f00;
-    color:#333;
-    background:#fff;
-    /* css3 */
-    -webkit-border-radius:10px;
-    -moz-border-radius:10px;
-    border-radius:10px;
-}
-
-/* Variant : for left positioned triangle
------------------------------------------- */
-
-.triangle-border.left {
-    margin-left:30px;
-}
-
-/* Variant : for right positioned triangle
------------------------------------------- */
-
-.triangle-border.right {
-    margin-right:30px;
-}
-
-.triangle-border:before {
-    content:"";
-    position:absolute;
-    bottom:-20px; /* value = - border-top-width - border-bottom-width */
-    left:40px; /* controls horizontal position */
-    border-width:20px 20px 0;
-    border-style:solid;
-    border-color:#5a8f00 transparent;
-    /* reduce the damage in FF3.0 */
-    display:block;
-    width:0;
-}
-
-/* creates the smaller  triangle */
-.triangle-border:after {
-    content:"";
-    position:absolute;
-    bottom:-13px; /* value = - border-top-width - border-bottom-width */
-    left:47px; /* value = (:before left) + (:before border-left) - (:after border-left) */
-    border-width:13px 13px 0;
-    border-style:solid;
-    border-color:#fff transparent;
-    /* reduce the damage in FF3.0 */
-    display:block;
-    width:0;
-}
-
-/* Variant : left
------------------------------------------- */
-
-/* creates the larger triangle */
-.triangle-border.left:before {
-    top:10px; /* controls vertical position */
-    bottom:auto;
-    left:-30px; /* value = - border-left-width - border-right-width */
-    border-width:15px 30px 15px 0;
-    border-color:transparent #5a8f00;
-}
-
-/* creates the smaller  triangle */
-.triangle-border.left:after {
-    top:16px; /* value = (:before top) + (:before border-top) - (:after border-top) */
-    bottom:auto;
-    left:-21px; /* value = - border-left-width - border-right-width */
-    border-width:9px 21px 9px 0;
-    border-color:transparent #fff;
-}
-
-/* Variant : right
------------------------------------------- */
-
-/* creates the larger triangle */
-.triangle-border.right:before {
-    top:10px; /* controls vertical position */
-    bottom:auto;
-    left:auto;
-    right:-30px; /* value = - border-left-width - border-right-width */
-    border-width:15px 0 15px 30px;
-    border-color:transparent #5a8f00;
-}
-
-/* creates the smaller  triangle */
-.triangle-border.right:after {
-    top:16px; /* value = (:before top) + (:before border-top) - (:after border-top) */
-    bottom:auto;
-    left:auto;
-    right:-21px; /* value = - border-left-width - border-right-width */
-    border-width:9px 0 9px 21px;
-    border-color:transparent #fff;
-}
+body{padding:0;margin:0;font:1em/1.4 Cambria,Georgia,sans-serif;color:#333;background:#fff}a:link,a:visited{border-bottom:1px solid #c55500;text-decoration:none;color:#c55500}a:visited{border-bottom:1px solid #730800;color:#730800}a:hover,a:focus,a:active{border:0;color:#fff;background:#c55500}a:visited:hover,a:visited:focus,a:visited:active{color:#fff;background:#730800}#container{width:500px;padding:0 0 50px;margin:0 auto}h1{margin:1em 0 0;font-size:2.5em;font-weight:normal;line-height:1.2;text-align:center}h2{margin:.5em 0 1.5em;font-size:1.25em;font-weight:normal;font-style:italic;text-align:center}p{margin:1em 0}.content h2{margin:2em 0 .75em;font-size:2em;font-weight:bold;font-style:normal;text-align:left}blockquote{margin:1em 0}blockquote p{margin:0;font-size:2em}.follow{clear:both;margin-top:2em;font-size:1.125em}.follow span{font-weight:bold}.content{position:relative;z-index:1}.triangle-isosceles{position:relative;padding:15px;margin:1em 0 3em;color:#000;background:#f3961c;background:-webkit-gradient(linear,0 0,0 100%,from(#f9d835),to(#f3961c));background:-moz-linear-gradient(#f9d835,#f3961c);background:-o-linear-gradient(#f9d835,#f3961c);background:linear-gradient(#f9d835,#f3961c);-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px}.triangle-isosceles.top{background:-webkit-gradient(linear,0 0,0 100%,from(#f3961c),to(#f9d835));background:-moz-linear-gradient(#f3961c,#f9d835);background:-o-linear-gradient(#f3961c,#f9d835);background:linear-gradient(#f3961c,#f9d835)}.triangle-isosceles.left{margin-left:50px;background:#f3961c}.triangle-isosceles.right{margin-right:50px;background:#f3961c}.triangle-isosceles:after{content:"";position:absolute;bottom:-15px;left:50px;border-width:15px 15px 0;border-style:solid;border-color:#f3961c transparent;display:block;width:0}.triangle-isosceles.top:after{top:-15px;right:50px;bottom:auto;left:auto;border-width:0 15px 15px;border-color:#f3961c transparent}.triangle-isosceles.left:after{top:16px;left:-50px;bottom:auto;border-width:10px 50px 10px 0;border-color:transparent #f3961c}.triangle-isosceles.right:after{top:16px;right:-50px;bottom:auto;left:auto;border-width:10px 0 10px 50px;border-color:transparent #f3961c}.triangle-right{position:relative;padding:15px;margin:1em 0 3em;color:#fff;background:#075698;background:-webkit-gradient(linear,0 0,0 100%,from(#2e88c4),to(#075698));background:-moz-linear-gradient(#2e88c4,#075698);background:-o-linear-gradient(#2e88c4,#075698);background:linear-gradient(#2e88c4,#075698);-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px}.triangle-right.top{background:-webkit-gradient(linear,0 0,0 100%,from(#075698),to(#2e88c4));background:-moz-linear-gradient(#075698,#2e88c4);background:-o-linear-gradient(#075698,#2e88c4);background:linear-gradient(#075698,#2e88c4)}.triangle-right.left{margin-left:40px;background:#075698}.triangle-right.right{margin-right:40px;background:#075698}.triangle-right:after{content:"";position:absolute;bottom:-20px;left:50px;border-width:20px 0 0 20px;border-style:solid;border-color:#075698 transparent;display:block;width:0}.triangle-right.top:after{top:-20px;right:50px;bottom:auto;left:auto;border-width:20px 20px 0 0;border-color:transparent #075698}.triangle-right.left:after{top:16px;left:-40px;bottom:auto;border-width:15px 40px 0 0;border-color:transparent #075698}.triangle-right.right:after{top:16px;right:-40px;bottom:auto;left:auto;border-width:15px 0 0 40px;border-color:transparent #075698}.triangle-obtuse{position:relative;padding:15px;margin:1em 0 3em;color:#fff;background:#c81e2b;background:-webkit-gradient(linear,0 0,0 100%,from(#f04349),to(#c81e2b));background:-moz-linear-gradient(#f04349,#c81e2b);background:-o-linear-gradient(#f04349,#c81e2b);background:linear-gradient(#f04349,#c81e2b);-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px}.triangle-obtuse.top{background:-webkit-gradient(linear,0 0,0 100%,from(#c81e2b),to(#f04349));background:-moz-linear-gradient(#c81e2b,#f04349);background:-o-linear-gradient(#c81e2b,#f04349);background:linear-gradient(#c81e2b,#f04349)}.triangle-obtuse.left{margin-left:50px;background:#c81e2b}.triangle-obtuse.right{margin-right:50px;background:#c81e2b}.triangle-obtuse:before{content:"";position:absolute;bottom:-20px;left:60px;border:0;border-right-width:30px;border-bottom-width:20px;border-style:solid;border-color:transparent #c81e2b;display:block;width:0}.triangle-obtuse:after{content:"";position:absolute;bottom:-20px;left:80px;border:0;border-right-width:10px;border-bottom-width:20px;border-style:solid;border-color:transparent #fff;display:block;width:0}.triangle-obtuse.top:before{top:-20px;bottom:auto;left:auto;right:60px;border:0;border-left-width:30px;border-top-width:20px;border-color:transparent #c81e2b}.triangle-obtuse.top:after{top:-20px;bottom:auto;left:auto;right:80px;border-width:0;border-left-width:10px;border-top-width:20px;border-color:transparent #fff}.triangle-obtuse.left:before{top:15px;bottom:auto;left:-50px;border:0;border-bottom-width:30px;border-left-width:50px;border-color:#c81e2b transparent}.triangle-obtuse.left:after{top:35px;bottom:auto;left:-50px;border:0;border-bottom-width:10px;border-left-width:50px;border-color:#fff transparent}.triangle-obtuse.right:before{top:15px;bottom:auto;left:auto;right:-50px;border:0;border-bottom-width:30px;border-right-width:50px;border-color:#c81e2b transparent}.triangle-obtuse.right:after{top:35px;bottom:auto;right:-50px;left:auto;border:0;border-bottom-width:10px;border-right-width:50px;border-color:#fff transparent}.triangle-border{position:relative;padding:15px;margin:1em 0 3em;color:#333;background:#fff;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px}.triangle-border.left{margin-left:30px;border:5px solid #a29d9d}.triangle-border.right{margin-right:30px;border:5px solid #5a8f00}.triangle-border:before{content:"";position:absolute;bottom:-20px;left:40px;border-width:20px 20px 0;border-style:solid;border-color:#5a8f00 transparent;display:block;width:0}.triangle-border:after{content:"";position:absolute;bottom:-13px;left:47px;border-width:13px 13px 0;border-style:solid;border-color:#fff transparent;display:block;width:0}.triangle-border.top:before{top:-20px;bottom:auto;left:auto;right:40px;border-width:0 20px 20px}.triangle-border.top:after{top:-13px;bottom:auto;left:auto;right:47px;border-width:0 13px 13px}.triangle-border.left:before{top:10px;bottom:auto;left:-30px;border-width:15px 30px 15px 0;border-color:transparent #a29d9d}.triangle-border.left:after{top:16px;bottom:auto;left:-21px;border-width:9px 21px 9px 0;border-color:transparent #fff}.triangle-border.right:before{top:10px;bottom:auto;left:auto;right:-30px;border-width:15px 0 15px 30px;border-color:transparent #5a8f00}.triangle-border.right:after{top:16px;bottom:auto;left:auto;right:-21px;border-width:9px 0 9px 21px;border-color:transparent #fff}.example-commentheading{position:relative;padding:0;color:#b513af}.example-commentheading:before{content:"";position:absolute;top:9px;left:-25px;width:15px;height:10px;background:#b513af;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.example-commentheading:after{content:"";position:absolute;top:15px;left:-19px;border:4px solid transparent;border-left-color:#b513af;display:block;width:0}.example-right{position:relative;padding:15px 30px;margin:0;color:#fff;background:#5a8f00;background:-webkit-gradient(linear,0 0,0 100%,from(#b8db29),to(#5a8f00));background:-moz-linear-gradient(#b8db29,#5a8f00);background:-o-linear-gradient(#b8db29,#5a8f00);background:linear-gradient(#b8db29,#5a8f00);-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px}.example-right+p{margin:15px 0 2em 85px;font-style:italic}.example-right:after{content:"";position:absolute;bottom:-50px;left:50px;border-width:0 20px 50px 0;border-style:solid;border-color:transparent #5a8f00;display:block;width:0}.example-obtuse{position:relative;padding:15px 30px;margin:0;color:#000;background:#f3961c;background:-webkit-gradient(linear,0 0,0 100%,from(#f9d835),to(#f3961c));background:-moz-linear-gradient(#f9d835,#f3961c);background:-o-linear-gradient(#f9d835,#f3961c);background:linear-gradient(#f9d835,#f3961c);-webkit-border-top-left-radius:25px 50px;-webkit-border-top-right-radius:25px 50px;-webkit-border-bottom-right-radius:25px 50px;-webkit-border-bottom-left-radius:25px 50px;-moz-border-radius:25px / 50px;border-radius:25px / 50px}.example-obtuse+p{margin:10px 150px 2em 0;text-align:right;font-style:italic}.example-obtuse:before{content:"";position:absolute;bottom:-30px;right:80px;border-width:0 0 30px 50px;border-style:solid;border-color:transparent #f3961c;display:block;width:0}.example-obtuse:after{content:"";position:absolute;bottom:-30px;right:110px;border-width:0 0 30px 20px;border-style:solid;border-color:transparent #fff;display:block;width:0}.example-twitter{position:relative;padding:15px;margin:100px 0 .5em;color:#333;background:#eee;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px}.example-twitter p{font-size:28px;line-height:1.25em}.example-twitter:before{content:url(twitter-logo.gif);position:absolute;top:-60px;left:0;width:155px;height:36px;display:block}.example-twitter:after{content:"";position:absolute;top:-30px;left:50px;border:15px solid transparent;border-bottom-color:#eee;display:block;width:0}.example-twitter+p{padding-left:15px;font:14px Arial,sans-serif}.example-number{position:relative;width:200px;height:200px;margin:50px 0 200px;text-align:center;font:140px/200px Arial,sans-serif;color:#fff;background:#c91f2c}.example-number:before{content:"";position:absolute;bottom:-140px;right:0;border-width:0 0 140px 140px;border-style:solid;border-color:transparent #c91f2c}.example-number:after{content:"";position:absolute;bottom:-140px;right:85px;border-width:0 0 140px 55px;border-style:solid;border-color:transparent #fff}.pinched{position:relative;padding:15px;margin:50px 0 3em;text-align:center;color:#fff;background:#333;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px}.pinched:before{content:"";position:absolute;top:-20px;left:50%;width:100px;height:20px;margin:0 0 0 -50px;background:#333}.pinched:after{content:"";position:absolute;top:-20px;left:0;width:50%;height:20px;background:#fff;-webkit-border-bottom-right-radius:15px;-moz-border-radius-bottomright:15px;border-bottom-right-radius:15px}.pinched>:first-child:before{content:"";position:absolute;top:-20px;right:0;width:50%;height:20px;background:#fff;-webkit-border-bottom-left-radius:15px;-moz-border-radius-bottomleft:15px;border-bottom-left-radius:15px}.oval-speech{position:relative;width:270px;padding:50px 40px;margin:1em auto 50px;text-align:center;color:#fff;background:#5a8f00;background:-webkit-gradient(linear,0 0,0 100%,from(#b8db29),to(#5a8f00));background:-moz-linear-gradient(#b8db29,#5a8f00);background:-o-linear-gradient(#b8db29,#5a8f00);background:linear-gradient(#b8db29,#5a8f00);-webkit-border-top-left-radius:220px 120px;-webkit-border-top-right-radius:220px 120px;-webkit-border-bottom-right-radius:220px 120px;-webkit-border-bottom-left-radius:220px 120px;-moz-border-radius:220px / 120px;border-radius:220px / 120px}.oval-speech p{font-size:1.25em}.oval-speech:before{content:"";position:absolute;z-index:-1;bottom:-30px;right:50%;height:30px;border-right:60px solid #5a8f00;background:#5a8f00;-webkit-border-bottom-right-radius:80px 50px;-moz-border-radius-bottomright:80px 50px;border-bottom-right-radius:80px 50px;-webkit-transform:translate(0,-2px);-moz-transform:translate(0,-2px);-ms-transform:translate(0,-2px);-o-transform:translate(0,-2px);transform:translate(0,-2px)}.oval-speech:after{content:"";position:absolute;z-index:-1;bottom:-30px;right:50%;width:60px;height:30px;background:#fff;-webkit-border-bottom-right-radius:40px 50px;-moz-border-radius-bottomright:40px 50px;border-bottom-right-radius:40px 50px;-webkit-transform:translate(-30px,-2px);-moz-transform:translate(-30px,-2px);-ms-transform:translate(-30px,-2px);-o-transform:translate(-30px,-2px);transform:translate(-30px,-2px)}.oval-thought{position:relative;width:270px;padding:50px 40px;margin:1em auto 80px;text-align:center;color:#fff;background:#075698;background:-webkit-gradient(linear,0 0,0 100%,from(#2e88c4),to(#075698));background:-moz-linear-gradient(#2e88c4,#075698);background:-o-linear-gradient(#2e88c4,#075698);background:linear-gradient(#2e88c4,#075698);-webkit-border-top-left-radius:220px 120px;-webkit-border-top-right-radius:220px 120px;-webkit-border-bottom-right-radius:220px 120px;-webkit-border-bottom-left-radius:220px 120px;-moz-border-radius:220px / 120px;border-radius:220px / 120px}.oval-thought p{font-size:1.25em}.oval-thought:before{content:"";position:absolute;bottom:-20px;left:50px;width:30px;height:30px;background:#075698;-webkit-border-radius:30px;-moz-border-radius:30px;border-radius:30px}.oval-thought:after{content:"";position:absolute;bottom:-30px;left:30px;width:15px;height:15px;background:#075698;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.oval-quotes{position:relative;width:400px;height:350px;margin:2em auto 10px;color:#000;background:#ffed26;-webkit-border-top-left-radius:400px 350px;-webkit-border-top-right-radius:400px 350px;-webkit-border-bottom-right-radius:400px 350px;-webkit-border-bottom-left-radius:400px 350px;-moz-border-radius:400px / 350px;border-radius:400px / 350px}.oval-quotes:before{content:"\201C";position:absolute;z-index:1;top:20px;left:20px;font:80px/1 Georgia,serif;color:#ffed26}.oval-quotes:after{content:"\201D";position:absolute;z-index:1;bottom:0;right:20px;font:80px/0.25 Georgia,serif;color:#ffed26}.oval-quotes p{width:250px;height:250px;padding:50px 0 0;margin:0 auto;text-align:center;font-size:35px}.oval-quotes p:before{content:"";position:absolute;z-index:-1;bottom:-30px;right:55%;width:180px;height:60px;background:#fff;-webkit-border-bottom-right-radius:40px 50px;-moz-border-radius-bottomright:40px 50px;border-bottom-right-radius:40px 50px;-webkit-transform:translate(-30px,-2px);-moz-transform:translate(-30px,-2px);-ms-transform:translate(-30px,-2px);-o-transform:translate(-30px,-2px);transform:translate(-30px,-2px)}.oval-quotes p:after{content:"";position:absolute;z-index:-2;bottom:-30px;right:25%;height:80px;border-right:200px solid #ffed26;background:#ffed26;-webkit-border-bottom-right-radius:200px 100px;-moz-border-radius-bottomright:200px 100px;border-bottom-right-radius:200px 100px;-webkit-transform:translate(0,-2px);-moz-transform:translate(0,-2px);-ms-transform:translate(0,-2px);-o-transform:translate(0,-2px);transform:translate(0,-2px);display:block;width:0}.oval-quotes+p{position:relative;width:150px;margin:0 0 2em;font-size:18px;font-weight:bold}.rectangle-speech-border{position:relative;padding:50px 15px;margin:1em 0 3em;border:10px solid #5a8f00;text-align:center;color:#333;background:#fff;-webkit-border-radius:20px;-moz-border-radius:20px;border-radius:20px}.rectangle-speech-border:before{content:"";position:absolute;z-index:10;bottom:-40px;left:50px;width:50px;height:30px;border-style:solid;border-width:0 10px 10px 0;border-color:#5a8f00;background:transparent;-webkit-border-bottom-right-radius:80px 50px;-moz-border-radius-bottomright:80px 50px;border-bottom-right-radius:80px 50px;display:block}.rectangle-speech-border:after{content:"";position:absolute;z-index:10;bottom:-40px;left:50px;width:20px;height:30px;border-style:solid;border-width:0 10px 10px 0;border-color:#5a8f00;background:transparent;-webkit-border-bottom-right-radius:40px 50px;-moz-border-radius-bottomright:40px 50px;border-bottom-right-radius:40px 50px;display:block}.rectangle-speech-border>:first-child:before{content:"";position:absolute;bottom:-40px;left:45px;width:10px;height:10px;background:#5a8f00;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px}.rectangle-speech-border>:first-child:after{content:"";position:absolute;bottom:-10px;left:76px;width:24px;height:15px;background:#fff}.oval-speech-border{position:relative;padding:70px 30px;margin:1em auto 60px;border:10px solid #f3961c;text-align:center;color:#333;background:#fff;-webkit-border-top-left-radius:240px 140px;-webkit-border-top-right-radius:240px 140px;-webkit-border-bottom-right-radius:240px 140px;-webkit-border-bottom-left-radius:240px 140px;-moz-border-radius:240px / 140px;border-radius:240px / 140px}.oval-speech-border:before{content:"";position:absolute;z-index:2;bottom:-40px;right:50%;width:50px;height:30px;border-style:solid;border-width:0 10px 10px 0;border-color:#f3961c;margin-right:-10px;background:transparent;-webkit-border-bottom-right-radius:80px 50px;-moz-border-radius-bottomright:80px 50px;border-bottom-right-radius:80px 50px;display:block}.oval-speech-border:after{content:"";position:absolute;z-index:2;bottom:-40px;right:50%;width:20px;height:31px;border-style:solid;border-width:0 10px 10px 0;border-color:#f3961c;margin-right:20px;background:transparent;-webkit-border-bottom-right-radius:40px 50px;-moz-border-radius-bottomright:40px 50px;border-bottom-right-radius:40px 50px;display:block}.oval-speech-border>:first-child:before{content:"";position:absolute;z-index:1;bottom:-40px;right:50%;width:10px;height:10px;margin-right:45px;background:#f3961c;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px}.oval-speech-border>:first-child:after{content:"";position:absolute;z-index:1;bottom:-10px;right:50%;width:30px;height:15px;background:#fff}.oval-thought-border{position:relative;padding:70px 30px;margin:1em auto 80px;border:10px solid #c81e2b;text-align:center;color:#333;background:#fff;-webkit-border-top-left-radius:240px 140px;-webkit-border-top-right-radius:240px 140px;-webkit-border-bottom-right-radius:240px 140px;-webkit-border-bottom-left-radius:240px 140px;-moz-border-radius:240px / 140px;border-radius:240px / 140px}.oval-thought-border:before{content:"";position:absolute;z-index:10;bottom:-40px;right:100px;width:50px;height:50px;border:10px solid #c81e2b;background:#fff;-webkit-border-radius:50px;-moz-border-radius:50px;border-radius:50px;display:block}.oval-thought-border:after{content:"";position:absolute;z-index:10;bottom:-60px;right:50px;width:25px;height:25px;border:10px solid #c81e2b;background:#fff;-webkit-border-radius:25px;-moz-border-radius:25px;border-radius:25px;display:block}
index a52e219..f4468c1 100644 (file)
@@ -5,7 +5,6 @@
 .path-mod-chat #messages-list,
 .path-mod-chat #users-list {list-style-type:none;padding:0;margin:0}
 .path-mod-chat #chat-header {overflow: hidden;}
-.path-mod-chat #chat-input-area table.generaltable td.cell {padding:1px;}
 
 /** styles for view.php **/
 #page-mod-chat-view .chatcurrentusers .chatuserdetails {vertical-align: middle;}
@@ -25,8 +24,8 @@
 
 /** YUI Overrides **/
 .path-mod-chat .yui-layout-unit-top {background: #FFE39D;}
-.path-mod-chat .yui-layout-unit-right {background: #FFD46B;}
-.path-mod-chat .yui-layout-unit-bottom {background: #FFCB44;}
+.path-mod-chat .yui-layout-unit-right {border-top: 5px solid white;background: #FFD46B;}
+.path-mod-chat .yui-layout-unit-bottom {border-top: 5px solid white;background: #FFCB44;}
 .path-mod-chat .yui-layout .yui-layout-hd {border:0;}
 .path-mod-chat .yui-layout .yui-layout-unit div.yui-layout-bd {border:0;background: transparent;}
 .path-mod-chat .yui-layout .yui-layout-unit div.yui-layout-unit-right {background: white;}
index 1bc946d..affb79e 100644 (file)
@@ -38,6 +38,15 @@ define('FEEDBACK_RESETFORM_DROP', 'feedback_drop_feedback_');
 define('FEEDBACK_MAX_PIX_LENGTH', '400'); //max. Breite des grafischen Balkens in der Auswertung
 define('FEEDBACK_DEFAULT_PAGE_COUNT', 20);
 
+/**
+ * Returns all other caps used in module.
+ *
+ * @return array
+ */
+function feedback_get_extra_capabilities() {
+    return array('moodle/site:accessallgroups');
+}
+
 /**
  * @uses FEATURE_GROUPS
  * @uses FEATURE_GROUPINGS
index 224f74c..0510643 100644 (file)
@@ -118,7 +118,7 @@ function label_delete_instance($id) {
  *
  * @global object
  * @param object $coursemodule
- * @return object|null
+ * @return cached_cm_info|null
  */
 function label_get_coursemodule_info($coursemodule) {
     global $DB;
index fa74bbc..56344b7 100644 (file)
 
 defined('MOODLE_INTERNAL') || die;
 
+/**
+ * Returns all other caps used in module.
+ *
+ * @return array
+ */
+function lti_get_extra_capabilities() {
+    return array('moodle/site:accessallgroups');
+}
+
 /**
  * List of features supported in URL module
  * @param string $feature FEATURE_xx constant for requested feature
index 81c40fd..d54ab66 100644 (file)
@@ -505,7 +505,7 @@ function lti_get_type_config($typeid) {
                 FROM {lti_types_config}
                WHERE typeid = :typeid1
            UNION ALL
-              SELECT 'toolurl' AS name, baseurl AS value
+              SELECT 'toolurl' AS name, " . $DB->sql_compare_text('baseurl', 1333) . " AS value
                 FROM {lti_types}
                WHERE id = :typeid2";
 
index fad61e6..b96f566 100644 (file)
@@ -33,7 +33,7 @@ use moodle\mod\lti as lti;
 
 $rawbody = file_get_contents("php://input");
 
-foreach (getallheaders() as $name => $value) {
+foreach (lti\OAuthUtil::get_headers() as $name => $value) {
     if ($name === 'Authorization') {
         // TODO: Switch to core oauthlib once implemented - MDL-30149
         $oauthparams = lti\OAuthUtil::split_header($value);
index 0f03e2a..9216337 100644 (file)
@@ -238,7 +238,7 @@ function page_user_complete($course, $user, $mod, $page) {
  *
  * See {@link get_array_of_activities()} in course/lib.php
  *
- * @param cm_info $coursemodule
+ * @param stdClass $coursemodule
  * @return cached_cm_info Info to customise main page display
  */
 function page_get_coursemodule_info($coursemodule) {
index e102b37..f76a1f9 100644 (file)
@@ -225,7 +225,7 @@ function resource_user_complete($course, $user, $mod, $resource) {
  *
  * See {@link get_array_of_activities()} in course/lib.php
  *
- * @param cm_info $coursemodule
+ * @param stdClass $coursemodule
  * @return cached_cm_info info
  */
 function resource_get_coursemodule_info($coursemodule) {
index 012847d..8433058 100644 (file)
@@ -243,7 +243,7 @@ function url_user_complete($course, $user, $mod, $url) {
  * See {@link get_array_of_activities()} in course/lib.php
  *
  * @param object $coursemodule
- * @return object info
+ * @return cached_cm_info info
  */
 function url_get_coursemodule_info($coursemodule) {
     global $CFG, $DB;
index d998aae..3fe6bc2 100644 (file)
 
 defined('MOODLE_INTERNAL') || die();
 
-$version  = 2013072400.00;              // YYYYMMDD      = weekly release date of this DEV branch
+$version  = 2013072600.01;              // YYYYMMDD      = weekly release date of this DEV branch
                                         //         RR    = release increments - 00 in DEV branches
                                         //           .XX = incremental changes
 
-$release  = '2.6dev (Build: 20130719)'; // Human-friendly version name
+$release  = '2.6dev (Build: 20130726)'; // Human-friendly version name
 
 $branch   = '26';                       // this version's branch
 $maturity = MATURITY_ALPHA;             // this version's maturity level