Super User

Super User

星期二, 14 4月 2020 05:44

国内开源商城分析比较(转载)

创业团队、创业公司必须要考虑的一个问题:产品/服务变现

不管是服务或 产品,变现就会有交易,简单的可以直接转账,稍微量大点或自动化点就要一个商城来承载。如果只需要商品展示+交易,可以直接使用有赞类的产品,其他不要折腾;但这次分析是低成本+少量需求定制的商城需求:

1 基础商城+少量定制功能,

2 支持小程序+h5,预算2w内,

3 重新开发成本太大,购买有赞类的SAAS,基本不能定制功能;

分析目标以php为主,正版商业源码,没有演示,不能下载源码的不在考虑范围。

分析维度:1~10分,6分及格

价格、框架、代码质量、用户版本、核心功能

 

1 tpshop, http://www.tp-shop.cn/

价格:5分

saas版本,5k

增强版本(h5+小程序):42800

详细:http://www.tp-shop.cn/price/

框架:8

php7+tp5(有java/c#版本)

代码质量:

用户版本:8分

h5+小程序+iOS+安卓都支持

核心功能:8分

单商户、多商户、分销、积分商城

 

2 商淘软件,https://www.shangtao.net/

价格:5

单商户商城,后台、小程序和H5版本源码价格是 15000元,带上双APP 是25000元

框架:8

php7+tp5

代码质量:7

用户版本:8

h5+小程序+iOS+安卓都支持

核心功能:8分

单商户、多商户、分销、积分商城

 

3 CRMEB开源系统,http://www.crmeb.com

价格:9

商业版:568,安装版:2098

框架:8

php7+tp5

代码质量:7

用户版本:6

h5+小程序

核心功能:5分

单商户、简单分销、无积分商城

 

4 荧火小程序商城,https://www.yiovo.com/

价格:8

商业版本:3k左右

框架:8

php7+tp5

代码质量:8

用户版本:4

小程序

核心功能:6

单商户、简单分销、积分兑换

 

5 来客推, http://www.laiketui.com/

价格:6

商业版本:小程序+h5+app,2.3w

框架:5

php5.5+自有框架

代码质量:5

核心功能:9

多商户、分销、积分商城、全版本

 

6 niushop,  https://www.niushop.com.cn/

价格:7

企业版本:4980

旗舰版本:7890

框架:8

php7+tp5

代码质量:7

核心功能:8

单商户、多商户、分销、积分、全版本

 

7 shopxo, https://shopxo.net/

价格:6

单域名:1980/4600/16800

不限域名:6800/12800/38800

框架:7

php7+tp5.1

代码质量:7

核心功能:5

单商户、会员等级、无积分、小程序UI简陋,演示版本功能太弱

 

8 dsshop, http://www.csdeshang.com/

价格:5

4000,6000,11000

框架:

php7+tp5.0

代码质量:6

核心功能:5

单/多商户,会员等级、会员积分,移动版本ui简陋

 

 转载自:知乎-创业公司-开源商城分析比较

 

星期五, 13 3月 2020 08:45

code样式测试

启动docker并设置自启动
sudo systemctl start docker
sudo systemctl enable docker
配置镜像,检查docker是否安装成功
星期二, 03 3月 2020 09:12

小程序登录鉴权

导语

为了方便小程序应用使用微信登录态进行授权登录,微信小程序提供了登录授权的开放接口。乍一看文档,感觉文档上讲的非常有道理,但是实现起来又真的是摸不着头脑,不知道如何管理和维护登录态。本文就来手把手的教会大家在业务里如何接入和维护微信登录态。


接入流程

这里官方文档上的流程图已经足够清晰,我们直接就该图展开详述和补充。

img

首先大家看到这张图,肯定会注意到小程序进行通信交互的不止是小程序前端和我们自己的服务端,微信第三方服务端也参与其中,那么微信服务端在其中扮演着怎样的角色呢?我们一起来串一遍登录鉴权的流程就明白了。

1. 调用wx.login生成code

wx.login()这个API的作用就是为当前用户生成一个临时的登录凭证,这个临时登录凭证的有效期只有五分钟。我们拿到这个登录凭证后就可以进行下一步操作:获取openid和session_key

wx.login({
    success: function(loginRes) {
        if (loginRes.code) {
            // example: 081LXytJ1Xq1Y40sg3uJ1FWntJ1LXyth
        }
    }
});

复制代码

2. 获取openid和session_key

我们先来介绍下openid,用过公众号的童鞋应该对这个标识都不陌生了,在公众平台里,用来标识每个用户在订阅号、服务号、小程序这三种不同应用的唯一标识,也就是说每个用户在每个应用的openid都是不一致的,所以在小程序里,我们可以用openid来标识用户的唯一性。

那么session_key是用来干嘛的呢?有了用户标识,我们就需要让该用户进行登录,那么session_key就保证了当前用户进行会话操作的有效性,这个session_key是微信服务端给我们派发的。也就是说,我们可以用这个标识来间接地维护我们小程序用户的登录态,那么这个session_key是怎么拿到的呢?我们需要在自己的服务端请求微信提供的第三方接口https://api.weixin.qq.com/sns/jscode2session,这个接口需要带上四个参数字段:

参数
appid 小程序的appid
secret 小程序的secret
js_code 前面调用wx.login派发的code
grant_type 'authorization_code'

从这几个参数,我们可以看出,要请求这个接口必须先调用wx.login()来获取到用户当前会话的code。那么为什么我们要在服务端来请求这个接口呢?其实是出于安全性的考量,如果我们在前端通过request调用此接口,就不可避免的需要将我们小程序的appid和小程序的secret暴露在外部,同时也将微信服务端下发的session_key暴露给“有心之人”,这就给我们的业务安全带来极大的风险。除了需要在服务端进行session_key的获取,我们还需要注意两点:

  • session_key和微信派发的code是一一对应的,同一code只能换取一次session_key。每次调用wx.login(),都会下发一个新的code和对应的session_key,为了保证用户体验和登录态的有效性,开发者需要清楚用户需要重新登录时才去调用wx.login()

  • session_key是有时效性的,即便是不调用wx.login,session_key也会过期,过期时间跟用户使用小程序的频率成正相关,但具体的时间长短开发者和用户都是获取不到的

function getSessionKey (code, appid, appSecret) {
    var opt = {
        method: 'GET',
        url: 'https://api.weixin.qq.com/sns/jscode2session',
        params: {
            appid: appid,
            secret: appSecret,
            js_code: code,
            grant_type: 'authorization_code'
        }
    };
    return http(opt).then(function (response) {
        var data = response.data;
        if (!data.openid || !data.session_key || data.errcode) {
            return {
                result: -2,
                errmsg: data.errmsg || '返回数据字段不完整'
            }
        } else {
            return data
        }
    });
}
复制代码

3. 生成3rd_session

前面说过通过session_key来“间接”地维护登录态,所谓间接,也就是我们需要自己维护用户的登录态信息,这里也是考虑到安全性因素,如果直接使用微信服务端派发的session_key来作为业务方的登录态使用,会被“有心之人”用来获取用户的敏感信息,比如wx.getUserInfo()这个接口呢,就需要session_key来配合解密微信用户的敏感信息。

那么我们如果生成自己的登录态标识呢,这里可以使用几种常见的不可逆的哈希算法,比如md5、sha1等,将生成后的登录态标识(这里我们统称为'skey')返回给前端,并在前端维护这份登录态标识(一般是存入storage)。而在服务端呢,我们会把生成的skey存在用户对应的数据表中,前端通过传递skey来存取用户的信息。

可以看到这里我们使用了sha1算法来生成了一个skey:

const crypto = require('crypto');

return getSessionKey(code, appid, secret)
    .then(resData => {
        // 选择加密算法生成自己的登录态标识
        const { session_key } = resData;
        const skey = encryptSha1(session_key);
    });
    
function encryptSha1(data) {
    return crypto.createHash('sha1').update(data, 'utf8').digest('hex')
}
复制代码

4. checkSession

前面我们将skey存入前端的storage里,每次进行用户数据请求时会带上skey,那么如果此时session_key过期呢?所以我们需要调用到wx.checkSession()这个API来校验当前session_key是否已经过期,这个API并不需要传入任何有关session_key的信息参数,而是微信小程序自己去调自己的服务来查询用户最近一次生成的session_key是否过期。如果当前session_key过期,就让用户来重新登录,更新session_key,并将最新的skey存入用户数据表中。

checkSession这个步骤呢,我们一般是放在小程序启动时就校验登录态的逻辑处,这里贴个校验登录态的流程图:

img2

下面代码即校验登录态的简单流程:

let loginFlag = wx.getStorageSync('skey');
if (loginFlag) {
    // 检查 session_key 是否过期
    wx.checkSession({
        // session_key 有效(未过期)
        success: function() {
            // 业务逻辑处理
        },
    
        // session_key 过期
        fail: function() {
            // session_key过期,重新登录
            doLogin();
        }
    });
) else {
    // 无skey,作为首次登录
    doLogin();
}
复制代码

5. 支持emoji表情存储

如果需要将用户微信名存入数据表中,那么就确认数据表及数据列的编码格式。因为用户微信名可能会包含emoji图标,而常用的UTF8编码只支持1-3个字节,emoji图标刚好是4个字节的编码进行存储。

这里有两种方式(以mysql为例):

1.设置存储字符集

在mysql5.5.3版本后,支持将数据库及数据表和数据列的字符集设置为utf8mb4,因此可在/etc/my.cnf设置默认字符集编码及服务端编码格式

// my.cnf

[client]
default-character-set=utf8mb4
[mysql]
default-character-set=utf8mb4
[mysqld]
character-set-client-handshake = FALSE
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
复制代码

设置完默认字符集编码及服务端字符集编码,如果是对已经存在的表和字段进行编码转换,需要执行下面几个步骤:

  • 设置数据库字符集为utf8mb4
ALTER DATABASE 数据库名称 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;

复制代码
  • 设置数据表字符集为utf8mb4
ALTER TABLE 数据表名称 CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

复制代码
  • 设置数据列字段字符集为utf8mb4
ALTER TABLE 数据表名称 CHANGE 字段列名称 VARCHAR(n) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

复制代码

这里的COLLATE指的是排序字符集,也就是用来对存储的字符进行排序和比较的,utf8mb4常用的collation有两种:utf8mb4_unicode_ci和utf8mb4_general_ci,一般建议使用utf8mb4_unicode_ci,因为它是基于标准的Unicode Collation Algorithm(UCA)来排序的,可以在各种语言进行精确排序。这两种排序方式的具体区别可以参考:What's the difference between utf8_general_ci and utf8_unicode_ci

  1. 通过使用sequelize对emoji字符进行编码入库,使用时再进行解码

这里是sequelize的配置,可参考Sequelize文档

{
       dialect: 'mysql',    // 数据库类型
       dialectOptions: {    
         charset: 'utf8mb4',
         collate: "utf8mb4_unicode_ci"
      },
}
复制代码

最后

前面讲了微信小程序如何接入微信登录态标识的详细流程,那么如何获取小程序中的用户数据以及对用户敏感数据进行解密,并保证用户数据的完整性,我将在下一篇文章给大家做一个详细地介绍。


作者:腾讯IVWEB团队
链接:https://juejin.im/post/5ac9b72cf265da23906c486a
来源:掘金

星期二, 03 3月 2020 05:48

使用JDatabase查询数据

Introduction

Joomla provides a sophisticated database abstraction layer to simplify the usage for third party developers. New versions of the Joomla Platform API provide additional functionality which extends the database layer further, and includes features such as connectors to a greater variety of database servers and the query chaining to improve readability of connection code and simplify SQL coding.

Joomla can use different kinds of SQL database systems and run in a variety of environments with different table-prefixes. In addition to these functions, the class automatically creates the database connection. Besides instantiating the object you need just two lines of code to get a result from the database in a variety of formats. Using the Joomla database layer ensures a maximum of compatibility and flexibility for your extension.

The Query

Joomla's database querying changed with the introduction of Joomla 1.6. The recommended way of building database queries is through "query chaining" (although string queries are still supported).

Query chaining refers to a method of connecting a number of methods, one after the other, with each method returning an object that can support the next method, improving readability and simplifying code.

To obtain a new instance of the JDatabaseQuery class we use the JDatabaseDriver getQuery method:

$db = JFactory::getDbo();

$query = $db->getQuery(true);

The JDatabaseDriver::getQuery takes an optional argument, $new, which can be true or false (the default being false).

To query our data source we can call a number of JDatabaseQuery methods; these methods encapsulate the data source's query language (in most cases SQL), hiding query-specific syntax from the developer and increasing the portability of the developer's source code.

Some of the more frequently used methods include; select, from, join, where and order. There are also methods such as insert, update and delete for modifying records in the data store. By chaining these and other method calls, you can create almost any query against your data store without compromising portability of your code.

Selecting Records from a Single Table

Below is an example of creating a database query using the JDatabaseQuery class. Using the select, from, where and order methods, we can create queries which are flexible, easily readable and portable:

// Get a db connection.
$db = JFactory::getDbo();

// Create a new query object.
$query = $db->getQuery(true);

// Select all records from the user profile table where key begins with "custom.".
// Order it by the ordering field.
$query->select($db->quoteName(array('user_id', 'profile_key', 'profile_value', 'ordering')));
$query->from($db->quoteName('#__user_profiles'));
$query->where($db->quoteName('profile_key') . ' LIKE ' . $db->quote('custom.%'));
$query->order('ordering ASC');

// Reset the query using our newly populated query object.
$db->setQuery($query);

// Load the results as a list of stdClass objects (see later for more options on retrieving data).
$results = $db->loadObjectList();

(Here the quoteName() function adds appropriate quotes around the column names to avoid conflicts with any database reserved word, now or in the future.)

The query can also be chained to simplify further:

$query
    ->select($db->quoteName(array('user_id', 'profile_key', 'profile_value', 'ordering')))
    ->from($db->quoteName('#__user_profiles'))
    ->where($db->quoteName('profile_key') . ' LIKE ' . $db->quote('custom.%'))
    ->order('ordering ASC');

Chaining method calls improves code readability and reduces code bloat as queries become longer and more complex.

Grouping can be achieved simply too. The following query would count the number of articles in each category.

$query
    ->select(array('catid', 'COUNT(*)'))
    ->from($db->quoteName('#__content'))
    ->group($db->quoteName('catid'));

A limit can be set to a query using "setLimit". For example in the following query, it would return up to 10 records.

$query
    ->select($db->quoteName(array('user_id', 'profile_key', 'profile_value', 'ordering')))
    ->from($db->quoteName('#__user_profiles'))
    ->setLimit('10');

 

Selecting Records from Multiple Tables

Using the JDatabaseQuery's join methods, we can select records from multiple related tables. The generic "join" method takes two arguments; the join "type" (inner, outer, left, right) and the join condition. In the following example you will notice that we can use all of the keywords we would normally use if we were writing a native SQL query, including the AS keyword for aliasing tables and the ON keyword for creating relationships between tables. Also note that the table alias is used in all methods which reference table columns (I.e. select, where, order).

// Get a db connection.
$db = JFactory::getDbo();

// Create a new query object.
$query = $db->getQuery(true);

// Select all articles for users who have a username which starts with 'a'.
// Order it by the created date.
// Note by putting 'a' as a second parameter will generate `#__content` AS `a`
$query
    ->select(array('a.*', 'b.username', 'b.name'))
    ->from($db->quoteName('#__content', 'a'))
    ->join('INNER', $db->quoteName('#__users', 'b') . ' ON ' . $db->quoteName('a.created_by') . ' = ' . $db->quoteName('b.id'))
    ->where($db->quoteName('b.username') . ' LIKE ' . $db->quote('a%'))
    ->order($db->quoteName('a.created') . ' DESC');

// Reset the query using our newly populated query object.
$db->setQuery($query);

// Load the results as a list of stdClass objects (see later for more options on retrieving data).
$results = $db->loadObjectList();

The join method above enables us to query both the content and user tables, retrieving articles with their author details. There are also convenience methods for joins:

We can use multiple joins to query across more than two tables:

$query
    ->select(array('a.*', 'b.username', 'b.name', 'c.*', 'd.*'))
    ->from($db->quoteName('#__content', 'a'))
    ->join('INNER', $db->quoteName('#__users', 'b') . ' ON ' . $db->quoteName('a.created_by') . ' = ' . $db->quoteName('b.id'))
    ->join('LEFT', $db->quoteName('#__user_profiles', 'c') . ' ON ' . $db->quoteName('b.id') . ' = ' . $db->quoteName('c.user_id'))
    ->join('RIGHT', $db->quoteName('#__categories', 'd') . ' ON ' . $db->quoteName('a.catid') . ' = ' . $db->quoteName('d.id'))
    ->where($db->quoteName('b.username') . ' LIKE ' . $db->quote('a%'))
    ->order($db->quoteName('a.created') . ' DESC');

Notice how chaining makes the source code much more readable for these longer queries.

In some cases, you will also need to use the AS clause when selecting items to avoid column name conflicts. In this case, multiple select statements can be chained in conjunction with using the second parameter of $db->quoteName.

$query
    ->select('a.*')
    ->select($db->quoteName('b.username', 'username'))
    ->select($db->quoteName('b.name', 'name'))
    ->from($db->quoteName('#__content', 'a'))
    ->join('INNER', $db->quoteName('#__users', 'b') . ' ON ' . $db->quoteName('a.created_by') . ' = ' . $db->quoteName('b.id'))
    ->where($db->quoteName('b.username') . ' LIKE ' . $db->quote('a%'))
    ->order($db->quoteName('a.created') . ' DESC');

A second array can also be used as the second parameter of the select statement to populate the values of the AS clause. Remember to include nulls in the second array to correspond to columns in the first array that you don't want to use the AS clause for:

$query
    ->select(array('a.*'))
    ->select($db->quoteName(array('b.username', 'b.name'), array('username', 'name')))
    ->from($db->quoteName('#__content', 'a'))
    ->join('INNER', $db->quoteName('#__users', 'b') . ' ON ' . $db->quoteName('a.created_by') . ' = ' . $db->quoteName('b.id'))
    ->where($db->quoteName('b.username') . ' LIKE ' . $db->quote('a%'))
    ->order($db->quoteName('a.created') . ' DESC');

 

Using OR in queries

When using multiple WHERE clauses in your query, they will be treated as an AND.

So, for example, the query below will return results where the 'name' field AND the 'state' field match.

$query = $db
    ->getQuery(true)
    ->select('COUNT(*)')
    ->from($db->quoteName('#__my_table'))
    ->where($db->quoteName('name') . " = " . $db->quote($value)
    ->where($db->quoteName('state') . " = " . $db->quote($state));

To use a WHERE clause as an OR, the query can be written like this

$query = $db
    ->getQuery(true)
    ->select('COUNT(*)')
    ->from($db->quoteName('#__my_table'))
    ->where($db->quoteName('name') . " = " . $db->quote($name_one), 'OR')
    ->where($db->quoteName('name') . " = " . $db->quote($name_two));

it can also be written like this

$query = $db
    ->getQuery(true)
    ->select('COUNT(*)')
    ->from($db->quoteName('#__my_table'))
    ->where($db->quoteName('name') . " = " . $db->quote($name_one)
    ->orWhere($db->quoteName('name') . " = " . $db->quote($name_two));

 

Query Results

The database class contains many methods for working with a query's result set.

Single Value Result

loadResult()

Use loadResult() when you expect just a single value back from your database query.

idnameemailusername
1 John Smith 该邮件地址已受到反垃圾邮件插件保护。要显示它需要在浏览器中启用 JavaScript。 johnsmith
2 Magda Hellman 该邮件地址已受到反垃圾邮件插件保护。要显示它需要在浏览器中启用 JavaScript。 magdah
3 Yvonne de Gaulle 该邮件地址已受到反垃圾邮件插件保护。要显示它需要在浏览器中启用 JavaScript。 ydegaulle

This is often the result of a 'count' query to get a number of records:

$db = JFactory::getDbo();
$query = $db
    ->getQuery(true)
    ->select('COUNT(*)')
    ->from($db->quoteName('#__my_table'))
    ->where($db->quoteName('name') . " = " . $db->quote($value));

// Reset the query using our newly populated query object.
$db->setQuery($query);
$count = $db->loadResult();

or where you are just looking for a single field from a single row of the table (or possibly a single field from the first row returned).

$db = JFactory::getDbo();
$query = $db
    ->getQuery(true)
    ->select('field_name')
    ->from($db->quoteName('#__my_table'))
    ->where($db->quoteName('some_name') . " = " . $db->quote($some_value));

$db->setQuery($query);
$result = $db->loadResult();

 

Single Row Results

Each of these results functions will return a single record from the database even though there may be several records that meet the criteria that you have set. To get more records you need to call the function again.

idnameemailusername
1 John Smith 该邮件地址已受到反垃圾邮件插件保护。要显示它需要在浏览器中启用 JavaScript。 johnsmith
2 Magda Hellman 该邮件地址已受到反垃圾邮件插件保护。要显示它需要在浏览器中启用 JavaScript。 magdah
3 Yvonne de Gaulle 该邮件地址已受到反垃圾邮件插件保护。要显示它需要在浏览器中启用 JavaScript。 ydegaulle

loadRow()

loadRow() returns an indexed array from a single record in the table:

. . .
$db->setQuery($query);
$row = $db->loadRow();
print_r($row);

will give:

Array ( [0] => 1, [1] => John Smith, [2] => 该邮件地址已受到反垃圾邮件插件保护。要显示它需要在浏览器中启用 JavaScript。, [3] => johnsmith ) 

You can access the individual values by using:

$row['index'] // e.g. $row['2']

Notes:

  1. The array indices are numeric starting from zero.
  2. Whilst you can repeat the call to get further rows, one of the functions that returns multiple rows might be more useful.

loadAssoc()

loadAssoc() returns an associated array from a single record in the table:

. . .
$db->setQuery($query);
$row = $db->loadAssoc();
print_r($row);

will give:

Array ( [id] => 1, [name] => John Smith, [email] => 该邮件地址已受到反垃圾邮件插件保护。要显示它需要在浏览器中启用 JavaScript。, [username] => johnsmith )

You can access the individual values by using:

$row['name'] // e.g. $row['email']

Notes:

  1. Whilst you can repeat the call to get further rows, one of the functions that returns multiple rows might be more useful.

loadObject()

loadObject returns a PHP object from a single record in the table:

. . .
$db->setQuery($query);
$result = $db->loadObject();
print_r($result);

will give:

stdClass Object ( [id] => 1, [name] => John Smith, [email] => 该邮件地址已受到反垃圾邮件插件保护。要显示它需要在浏览器中启用 JavaScript。, [username] => johnsmith )

You can access the individual values by using:

$result->index // e.g. $result->email

Notes:

  1. Whilst you can repeat the call to get further rows, one of the functions that returns multiple rows might be more useful.

Single Column Results

Each of these results functions will return a single column from the database.

idnameemailusername
1 John Smith 该邮件地址已受到反垃圾邮件插件保护。要显示它需要在浏览器中启用 JavaScript。 johnsmith
2 Magda Hellman 该邮件地址已受到反垃圾邮件插件保护。要显示它需要在浏览器中启用 JavaScript。 magdah
3 Yvonne de Gaulle 该邮件地址已受到反垃圾邮件插件保护。要显示它需要在浏览器中启用 JavaScript。 ydegaulle

loadColumn()

loadColumn() returns an indexed array from a single column in the table:

$query->select('name'));
      ->from . . .";
. . .
$db->setQuery($query);
$column= $db->loadColumn();
print_r($column);

will give:

Array ( [0] => John Smith, [1] => Magda Hellman, [2] => Yvonne de Gaulle )

You can access the individual values by using:

$column['index'] // e.g. $column['2']

Notes:

  1. The array indices are numeric starting from zero.
  2. loadColumn() is equivalent to loadColumn(0).

loadColumn($index)

loadColumn($index) returns an indexed array from a single column in the table:

$query->select(array('name', 'email', 'username'));
      ->from . . .";
. . .
$db->setQuery($query);
$column= $db->loadColumn(1);
print_r($column);

will give:

Array ( [0] => 该邮件地址已受到反垃圾邮件插件保护。要显示它需要在浏览器中启用 JavaScript。, [1] => 该邮件地址已受到反垃圾邮件插件保护。要显示它需要在浏览器中启用 JavaScript。, [2] => 该邮件地址已受到反垃圾邮件插件保护。要显示它需要在浏览器中启用 JavaScript。 )

You can access the individual values by using:

$column['index'] // e.g. $column['2']

loadColumn($index) allows you to iterate through a series of columns in the results

. . .
$db->setQuery($query);
for ( $i = 0; $i <= 2; $i++ ) {
  $column= $db->loadColumn($i);
  print_r($column);
}

will give:

Array ( [0] => John Smith, [1] => Magda Hellman, [2] => Yvonne de Gaulle ),
Array ( [0] => 该邮件地址已受到反垃圾邮件插件保护。要显示它需要在浏览器中启用 JavaScript。, [1] => 该邮件地址已受到反垃圾邮件插件保护。要显示它需要在浏览器中启用 JavaScript。, [2] => 该邮件地址已受到反垃圾邮件插件保护。要显示它需要在浏览器中启用 JavaScript。 ),
Array ( [0] => johnsmith, [1] => magdah, [2] => ydegaulle )

Notes:

  1. The array indices are numeric starting from zero.

Multi-Row Results

Each of these results functions will return multiple records from the database.

idnameemailusername
1 John Smith 该邮件地址已受到反垃圾邮件插件保护。要显示它需要在浏览器中启用 JavaScript。 johnsmith
2 Magda Hellman 该邮件地址已受到反垃圾邮件插件保护。要显示它需要在浏览器中启用 JavaScript。 magdah
3 Yvonne de Gaulle 该邮件地址已受到反垃圾邮件插件保护。要显示它需要在浏览器中启用 JavaScript。 ydegaulle

loadRowList()

loadRowList() returns an indexed array of indexed arrays from the table records returned by the query:

. . .
$db->setQuery($query);
$row = $db->loadRowList();
print_r($row);

will give (with line breaks added for clarity):

Array ( 
[0] => Array ( [0] => 1, [1] => John Smith, [2] => 该邮件地址已受到反垃圾邮件插件保护。要显示它需要在浏览器中启用 JavaScript。, [3] => johnsmith ), 
[1] => Array ( [0] => 2, [1] => Magda Hellman, [2] => 该邮件地址已受到反垃圾邮件插件保护。要显示它需要在浏览器中启用 JavaScript。, [3] => magdah ), 
[2] => Array ( [0] => 3, [1] => Yvonne de Gaulle, [2] => 该邮件地址已受到反垃圾邮件插件保护。要显示它需要在浏览器中启用 JavaScript。, [3] => ydegaulle ) 
)

You can access the individual rows by using:

$row['index'] // e.g. $row['2']

and you can access the individual values by using:

$row['index']['index'] // e.g. $row['2']['3']

Notes:

  1. The array indices are numeric starting from zero.

loadAssocList()

loadAssocList() returns an indexed array of associated arrays from the table records returned by the query:

. . .
$db->setQuery($query);
$row = $db->loadAssocList();
print_r($row);

will give (with line breaks added for clarity):

Array ( 
[0] => Array ( [id] => 1, [name] => John Smith, [email] => 该邮件地址已受到反垃圾邮件插件保护。要显示它需要在浏览器中启用 JavaScript。, [username] => johnsmith ), 
[1] => Array ( [id] => 2, [name] => Magda Hellman, [email] => 该邮件地址已受到反垃圾邮件插件保护。要显示它需要在浏览器中启用 JavaScript。, [username] => magdah ), 
[2] => Array ( [id] => 3, [name] => Yvonne de Gaulle, [email] => 该邮件地址已受到反垃圾邮件插件保护。要显示它需要在浏览器中启用 JavaScript。, [username] => ydegaulle ) 
) 

You can access the individual rows by using:

$row['index'] // e.g. $row['2']

and you can access the individual values by using:

$row['index']['column_name'] // e.g. $row['2']['email']

loadAssocList($key)

loadAssocList('key') returns an associated array - indexed on 'key' - of associated arrays from the table records returned by the query:

. . .
$db->setQuery($query);
$row = $db->loadAssocList('username');
print_r($row);

will give (with line breaks added for clarity):

Array ( 
[johnsmith] => Array ( [id] => 1, [name] => John Smith, [email] => 该邮件地址已受到反垃圾邮件插件保护。要显示它需要在浏览器中启用 JavaScript。, [username] => johnsmith ), 
[magdah] => Array ( [id] => 2, [name] => Magda Hellman, [email] => 该邮件地址已受到反垃圾邮件插件保护。要显示它需要在浏览器中启用 JavaScript。, [username] => magdah ), 
[ydegaulle] => Array ( [id] => 3, [name] => Yvonne de Gaulle, [email] => 该邮件地址已受到反垃圾邮件插件保护。要显示它需要在浏览器中启用 JavaScript。, [username] => ydegaulle ) 
)

You can access the individual rows by using:

$row['key_value'] // e.g. $row['johnsmith']

and you can access the individual values by using:

$row['key_value']['column_name'] // e.g. $row['johnsmith']['email']

Note: Key must be a valid column name from the table; it does not have to be an Index or a Primary Key. But if it does not have a unique value you may not be able to retrieve results reliably.

loadAssocList($key, $column)

loadAssocList('key', 'column') returns an associative array, indexed on 'key', of values from the column named 'column' returned by the query:

. . .
$db->setQuery($query);
$row = $db->loadAssocList('id', 'username');
print_r($row);

will give (with line breaks added for clarity):

Array ( 
[1] => John Smith, 
[2] => Magda Hellman, 
[3] => Yvonne de Gaulle,
)

Note: Key must be a valid column name from the table; it does not have to be an Index or a Primary Key. But if it does not have a unique value you may not be able to retrieve results reliably.

loadObjectList()

loadObjectList() returns an indexed array of PHP objects from the table records returned by the query:

. . .
$db->setQuery($query);
$row = $db->loadObjectList();
print_r($row);

will give (with line breaks added for clarity):

Array ( 
[0] => stdClass Object ( [id] => 1, [name] => John Smith, 
    [email] => 该邮件地址已受到反垃圾邮件插件保护。要显示它需要在浏览器中启用 JavaScript。, [username] => johnsmith ), 
[1] => stdClass Object ( [id] => 2, [name] => Magda Hellman, 
    [email] => 该邮件地址已受到反垃圾邮件插件保护。要显示它需要在浏览器中启用 JavaScript。, [username] => magdah ), 
[2] => stdClass Object ( [id] => 3, [name] => Yvonne de Gaulle, 
    [email] => 该邮件地址已受到反垃圾邮件插件保护。要显示它需要在浏览器中启用 JavaScript。, [username] => ydegaulle ) 
)

You can access the individual rows by using:

$row['index'] // e.g. $row['2']

and you can access the individual values by using:

$row['index']->name // e.g. $row['2']->email

loadObjectList($key)

loadObjectList('key') returns an associated array - indexed on 'key' - of objects from the table records returned by the query:

. . .
$db->setQuery($query);
$row = $db->loadObjectList('username');
print_r($row);

will give (with line breaks added for clarity):

Array ( 
[johnsmith] => stdClass Object ( [id] => 1, [name] => John Smith, 
    [email] => 该邮件地址已受到反垃圾邮件插件保护。要显示它需要在浏览器中启用 JavaScript。, [username] => johnsmith ), 
[magdah] => stdClass Object ( [id] => 2, [name] => Magda Hellman, 
    [email] => 该邮件地址已受到反垃圾邮件插件保护。要显示它需要在浏览器中启用 JavaScript。, [username] => magdah ), 
[ydegaulle] => stdClass Object ( [id] => 3, [name] => Yvonne de Gaulle, 
    [email] => 该邮件地址已受到反垃圾邮件插件保护。要显示它需要在浏览器中启用 JavaScript。, [username] => ydegaulle ) 
)

You can access the individual rows by using:

$row['key_value'] // e.g. $row['johnsmith']

and you can access the individual values by using:

$row['key_value']->column_name // e.g. $row['johnsmith']->email

Note: Key must be a valid column name from the table; it does not have to be an Index or a Primary Key. But if it does not have a unique value you may not be able to retrieve results reliably.

Miscellaneous Result Set Methods

getNumRows()

getNumRows() will return the number of result rows found by the last SELECT or SHOW query and waiting to be read. To get a result from getNumRows() you have to run it after the query and before you have retrieved any results. To retrieve the number of rows affected by a INSERT, UPDATE, REPLACE or DELETE query, use getAffectedRows().

. . .
$db->setQuery($query);
$db->execute();
$num_rows = $db->getNumRows();
print_r($num_rows);
$result = $db->loadRowList();

will return

3

Note: getNumRows() is only valid for statements like SELECT or SHOW that return an actual result set. If you run getNumRows() after loadRowList() - or any other retrieval method - you will get a PHP Warning:

Warning: mysql_num_rows(): 80 is not a valid MySQL result resource 
in libraries\joomla\database\database\mysql.php on line 344
星期二, 03 3月 2020 05:34

joomla数据库处理

使用Joomla数据库的通用步骤:

$db = JFactory::getDbo();

$query = $db->getQuery(true);

$db->setQuery($query);

$db->execute();或者$results = $db->loadObjectList();

 

引言

Joomla provides a sophisticated database abstraction layer to simplify the usage for third party developers. New versions of the Joomla Platform API provide additional functionality which extends the database layer further, and includes features such as connectors to a greater variety of database servers and the query chaining to improve readability of connection code and simplify SQL coding.

Joomla can use different kinds of SQL database systems and run in a variety of environments with different table-prefixes. In addition to these functions, the class automatically creates the database connection. Besides instantiating the object you need just two lines of code to get a result from the database in a variety of formats. Using the Joomla database layer ensures a maximum of compatibility and flexibility for your extension.

The Query

Joomla's database querying has changed since the new Joomla Framework was introduced "query chaining" is now the recommended method for building database queries (although string queries are still supported).

Query chaining refers to a method of connecting a number of methods, one after the other, with each method returning an object that can support the next method, improving readability and simplifying code.

To obtain a new instance of the JDatabaseQuery class we use the JDatabaseDriver getQuery method:

$db = JFactory::getDbo();

$query = $db->getQuery(true);

The JDatabaseDriver::getQuery takes an optional argument, $new, which can be true or false (the default being false).

To query our data source we can call a number of JDatabaseQuery methods; these methods encapsulate the data source's query language (in most cases SQL), hiding query-specific syntax from the developer and increasing the portability of the developer's source code.

Some of the more frequently used methods include; select, from, join, where and order. There are also methods such as insert, update and delete for modifying records in the data store. By chaining these and other method calls, you can create almost any query against your data store without compromising portability of your code.

Inserting a Record

Using SQL

The JDatabaseQuery class provides a number of methods for building insert queries, the most common being insertcolumns and values.

// Get a db connection.
$db = JFactory::getDbo();

// Create a new query object.
$query = $db->getQuery(true);

// Insert columns.
$columns = array('user_id', 'profile_key', 'profile_value', 'ordering');

// Insert values.
$values = array(1001, $db->quote('custom.message'), $db->quote('Inserting a record using insert()'), 1);

// Prepare the insert query.
$query
    ->insert($db->quoteName('#__user_profiles'))
    ->columns($db->quoteName($columns))
    ->values(implode(',', $values));

// Set the query using our newly populated query object and execute it.
$db->setQuery($query);
$db->execute();

(Here the quoteName() function adds appropriate quotes around the table and column names to avoid conflicts with any database reserved word, now or in the future.)

Using an Object

The JDatabaseDriver class also provides a convenient method for saving an object directly to the database allowing us to add a record to a table without writing a single line of SQL.

// Create and populate an object.
$profile = new stdClass();
$profile->user_id = 1001;
$profile->profile_key='custom.message';
$profile->profile_value='Inserting a record using insertObject()';
$profile->ordering=1;

// Insert the object into the user profile table.
$result = JFactory::getDbo()->insertObject('#__user_profiles', $profile);

Notice here that we do not need to escape the table name; the insertObject method does this for us.

The insertObject method will throw a error if there is a problem inserting the record into the database table.

If you are providing a unique primary key value (as in the example above), it is highly recommended that you select from the table by that column value before attempting an insert.

If you are simply inserting the next row in your table (i.e. the database generates a primary key value), you can specify the primary key column-name as the third parameter of the insertObject() method and the method will update the object with the newly generated primary key value.

For example, given the following statement:

$result = $dbconnect->insertObject('#__my_table', $object, 'primary_key');

after execution, $object->primary_key will be updated with the newly inserted row's primary key value.

HINT: Set $object->primary_key to null or 0 (zero) before inserting.

Updating a Record

Using SQL

The JDatabaseQuery class also provides methods for building update queries, in particular update and set. We also reuse another method which we used when creating select statements, the where method.

$db = JFactory::getDbo();

$query = $db->getQuery(true);

// Fields to update.
$fields = array(
    $db->quoteName('profile_value') . ' = ' . $db->quote('Updating custom message for user 1001.'),
    $db->quoteName('ordering') . ' = 2'
);

// Conditions for which records should be updated.
$conditions = array(
    $db->quoteName('user_id') . ' = 42', 
    $db->quoteName('profile_key') . ' = ' . $db->quote('custom.message')
);

$query->update($db->quoteName('#__user_profiles'))->set($fields)->where($conditions);

$db->setQuery($query);

$result = $db->execute();

Using an Object

Like insertObject, the JDatabaseDriver class provides a convenience method for updating an object.

Below we will update our custom table with new values using an existing id primary key:

// Create an object for the record we are going to update.
$object = new stdClass();

// Must be a valid primary key value.
$object->id = 1;
$object->title = 'My Custom Record';
$object->description = 'A custom record being updated in the database.';

// Update their details in the users table using id as the primary key.
$result = JFactory::getDbo()->updateObject('#__custom_table', $object, 'id');

Just like insertObject, updateObject takes care of escaping table names for us.

The updateObject method will throw a error if there is a problem updating the record into the database table.

We need to ensure that the record already exists before attempting to update it, so we would probably add some kind of record check before executing the updateObject method.

Deleting a Record

Finally, there is also a delete method to remove records from the database.

$db = JFactory::getDbo();

$query = $db->getQuery(true);

// delete all custom keys for user 1001.
$conditions = array(
    $db->quoteName('user_id') . ' = 1001', 
    $db->quoteName('profile_key') . ' = ' . $db->quote('custom.%')
);

$query->delete($db->quoteName('#__user_profiles'));
$query->where($conditions);

$db->setQuery($query);

$result = $db->execute();

Sample Module Code

Below is the code for a simple Joomla module which you can install and run to demonstrate use of the JDatabase functionality for updating records in the database, and which you can adapt to experiment with some of the concepts described above. If you are unsure about development and installing a Joomla module then following the tutorial at Creating a simple module will help.

Important note: In any Joomla extensions which you develop that you should avoid accessing the core Joomla tables directly like this and should instead use the Joomla APIs if at all possible, because the database structures may change without warning.

In a folder mod_db_update create the following 2 files:

mod_db_update.xml

<?xml version="1.0" encoding="utf-8"?>
<extension type="module" version="3.1" client="site" method="upgrade">
    <name>Database update demo</name>
    <version>1.0.1</version>
    <description>Code demonstrating use of Joomla Database class to perform SQL UPDATE statements</description>
    <files>
        <filename module="mod_db_update">mod_db_update.php</filename>
    </files>
</extension>

mod_db_update.php

<?php
defined('_JEXEC') or die('Restricted Access');

use Joomla\CMS\Factory;

$db = Factory::getDbo();

$me = Factory::getUser();

if ($me->id == 0)
{
	echo "Not logged on!";
}
else
{
	$email = $me->email; 
	// change the case of the email address
	$email_uppercase = strtoupper($email);
	if ($email == $email_uppercase)
	{
		$new_email = strtolower($email);
	}
	else
	{
		$new_email = $email_uppercase;
	}
	
	$query = $db->getQuery(true);

	$fields = array($db->quoteName('email') . " = '{$new_email}'");

	$conditions = array($db->quoteName('id') . ' = ' . $me->id); 

	$query->update($db->quoteName('#__users'))->set($fields)->where($conditions);

	echo $db->replacePrefix((string) $query);
	
	$db->setQuery($query);

	if ($result = $db->execute())
	{
		echo "Email case successfully changed!";
	}
}

The code above updates the email address field in the users record of the currently logged-on user, toggling between upper case and lower case in successive reloads of the web page.

The method Factory::getUser() returns the user object of the currently logged-on user, or if not logged on, then a blank user object, whose id field is set to zero.

The $db->replacePrefix((string) $query) expression returns the actual SQL statement, and outputting this can be useful in debugging.

Zip up the mod_db_update directory to create mod_db_update.zip.

Within your Joomla administrator go to Install Extensions and via the Upload Package File tab upload this zip file to install this sample log module.

Make this module visible by editing it (click on it within the Modules page) then:

  1. making its status Published
  2. selecting a position on the page for it to be shown
  3. on the menu assignment tab specify the pages it should appear on

When you visit a site web page then you should see the module in your selected position, and it should output the SQL UPDATE statement and affirm that it has updated the record successfully. To confirm that it has updated the record correctly go into phpmyadmin and view the users table within the Joomla database. The updates aren't visible via the admin Users functionality on the back end, as Joomla displays in lower case all the email addresses in the records.

星期二, 03 3月 2020 02:29

使用Joomla!日志Log

 

Overview

Joomla logging gives you the ability to log messages to files and to the screen (within the Joomla! Debug Console at the bottom of the web page) and the main Joomla class which underpins this is JLog. In the new naming convention this is the Log class within the namespace Joomla\CMS\Log\Log.

The logging can be controlled dynamically through the Joomla Global Configuration and by configuring the System – Debug plugin (which is shipped with Joomla). Overall these facilities allow you to:

  • switch DEBUG logging on or off – so that ordinarily you don't consume resources needlessly, but you have the logging information to assist troubleshooting when there are issues, for example on a live site which has your extension installed.
  • route log messages to a specific log file for your own extension.
  • view log messages in the Debug Console – you can select the group of users to which log messages should be displayed, so that on a live site developers can see the messages while other users are unaffected.
  • filter Debug Console messages by priority (i.e. INFO, DEBUG, WARNING and so on) and by category. (You are free to define your own categories.)

In addition, the log messages can be translatable into different languages.

The main configuration options relating to logging are shown below. Switching on debug and display of the Joomla Debug Console is controlled through the global configuration options.

Global conf debug-en.jpg

Logging to the general log file is controlled via the Logging tab of the configuration of the Joomla System - Debug plugin. (In the administrator menu, click on Extensions / Plugins, find the System - Debug plugin. Click on it to edit its configurable options).

Debug logging settings-en.jpg

And the options within the Plugin tab control display on the Joomla Debug Console.

Debug plugin settings-en.jpg

Basic File Logging

To log a message you use the JLog::add() function. For example:

JLog::add('my error message', JLog::ERROR, 'my-error-category');

Using the new class naming convention use instead:

use Joomla\CMS\Log\Log;
Log::add('my error message', Log::ERROR, 'my-error-category');

The parameters are

  1. A message string. You can use translation with these. (For example, JText::_('MY_EXTENSION_ERR_MSG') You can also display the values of variables, provided you convert them into a string format. (For example, using __toString() if the type of the variable supports that.)
  2. A priority, which can be one of JLog::EMERGENCY, JLog::ALERT, JLog::CRITICAL, JLog::ERROR, JLog::WARNING, JLog::NOTICE, JLog::INFO, JLog::DEBUG (based on the standard syslog / RFC 5424 severity levels – see wikipedia article on syslog).
  3. A category, which is just a text string. You can define whatever categories you like, but it is best to define them to avoid possible clashes with those of other extensions.

It can be very helpful with troubleshooting problems if you include diagnostic debug messages in your extension. In this case, enclose your log message within a check for JDEBUG:

if (JDEBUG)
{
    JLog::add('my debug message', JLog::DEBUG, 'my-debug-category');
}

Basic Logging Sample Code

Below is the code for a simple Joomla module which you can install and run to demonstrate use of the logging functionality. If you are unsure about development and installing a Joomla module then following the tutorial at Creating a simple module will help.

In a folder mod_sample_log create the following 2 files:

mod_sample_log.xml

<?xml version="1.0" encoding="utf-8"?>
<extension type="module" version="3.1" client="site" method="upgrade">
<name>Joomla Log demo</name>
<version>1.0.1</version>
<description>Code demonstrating use of Joomla Log class to log messages</description>
<files>
<filename module="mod_sample_log">mod_sample_log.php</filename>
</files>
</extension>

mod_sample_log.php

<?php
defined('_JEXEC') or die('Restricted Access');

use Joomla\CMS\Log\Log;

Log::add('my error message', Log::ERROR, 'my-error-category');

JLog::add('my old error message', JLog::WARNING, 'my-old-error-category');

echo "Error message logged";

Zip up the mod_sample_log directory to create mod_sample_log.zip.

Within your Joomla administrator go to Install Extensions and via the Upload Package File tab select this zip file to install this sample log module.

Make this module visible by editing it (click on it within the Modules page) then:

  1. making its status Published
  2. selecting a position on the page for it to be shown
  3. on the menu assignment tab specify the pages it should appear on

Check the configuration of the settings shown at the top of this web page. In particular, ensure that the System – Debug plugin is enabled and that Log Almost Everything is set to Yes. Also note where the folder where your log files are stored.

Display your Joomla site and you should then see the sample log module appearing. In your log file folder you should find your error messages in the everything.php file.

Also switch on the debug console and confirm that you can see the error messages in its Log Messages section.

Logging to a Specific Log File

You can use JLog::addLogger() to set up logging to an additional log file, filtering the log messages to be sent there by priority (the 'severity level') and/or category. The parameters of JLog::addLogger() are:

  1. an array with configuration details – including the name of the log file.
  2. the severity levels to be logged in that file.
  3. an array of the categories to be logged in that file. (If parameter 4 is set to true, this array defines the categories which are NOT to be logged in the file.)
  4. (often omitted) a boolean specifying whether parameter 3 is an include list. (The default, P4 = false) or an exclude list (P4 = true.)

For example, if you have developed a com_helloworld extension you could use the following:

JLog::addLogger(
    array(
         // Sets file name
         'text_file' => 'com_helloworld.log.php'
    ),
    // Sets messages of all log levels to be sent to the file.
    JLog::ALL,
    // The log category/categories which should be recorded in this file.
    // In this case, it's just the one category from our extension.
    // We still need to put it inside an array.
    array('com_helloworld')
);

Then when you log a message, specify the category as com_helloworld, as in the example below

JLog::add(JText::_('COM_HELLOWORLD_ERROR_MESSAGE_123'), JLog::ERROR, 'com_helloworld');

This will result in your log message being written to com_helloworld.log.php. If the System – Debug plugin settings have "Log Almost Everything" set to Yes, the message will appear in the common everything.php log file as well.

Note: You may wish to combine this with the Display error messages and notices section to display visible error notifications to users.

You can also add an additional logger to capture only critical and emergency log notifications:

JLog::addLogger(
    array(
         // Sets file name.
         'text_file' => 'com_helloworld.critical_emergency.php'
    ),
    // Sets critical and emergency log level messages to be sent to the file.
    JLog::CRITICAL + JLog::EMERGENCY,
    // The log category which should be recorded in this file.
    array('com_helloworld')
);

You can also exclude a specific priority level from being included. For example, to log all but DEBUG messages:

JLog::addLogger(
    array(
         // Sets file name.
         'text_file' => 'com_helloworld.all_but_debug.php'
    ),
    // Sets all but DEBUG log level messages to be sent to the file.
    JLog::ALL & ~JLog::DEBUG,
    // The log category which should be recorded in this file.
    array('com_helloworld')
);

The JLog priority levels are implemented as separate bits of an integer, so you can use bitwise operations (bitwise AND, &; and bitwise NOT, ~) to calculate the appropriate log levels. JLog::All is a constant integer which has all the relevant bits set, so that all the Joomla priority levels are included.

Formatting the Log File

The first parameter to addLogger can have a few optional additional settings in addition to the text_file entry.

There is, for example, the entry text_entry_format, specifying the format of each line in your log file.

The default format is:

   '{DATETIME} {PRIORITY}      {CATEGORY}      {MESSAGE}'

Here is an example of a different format which shows how to omit the category:

JLog::addLogger(
    array(
         // Sets file name.
         'text_file' => 'com_helloworld.critical_emergency.php',
         // Sets the format of each line.
         'text_entry_format' => '{DATETIME} {PRIORITY} {MESSAGE}'
    ),
    // Sets all but DEBUG log level messages to be sent to the file.
    JLog::ALL & ~JLog::DEBUG,
    // The log category which should be recorded in this file.
    array('com_helloworld')
);

In addition to the placeholders shown above in the default string, the following values are available:

   {CLIENTIP}      (this is the IP address of the client)
   {TIME}
   {DATE}

There is an additional optional boolean parameter text_file_no_php, which specifies whether the log file is prepended with the usual prefix of:

   #
   #<?php die('Forbidden.');?>

Note: Usually you should not set this setting to false. Log files should not be readable from the outside. They can provide valuable information about your system for attackers. Only dabble with this if you know what you're doing!

Furthermore, if you want to store the log file somewhere other than the logging path configured in the Joomla! settings, there is the text_file_path setting.

Logging to Other Places

As well as logging to files, you can log to other places as well, such as

  • the Joomla message area (where the message is shown if you call JFactory::getApplication()->enqueueMessage()).
  • a database table.
  • just a simple echo statement.

Of these, probably the most useful is the logging to the message bar, which you can set up via:

JLog::addLogger(array('logger' => 'messagequeue'), JLog::ALL, array('msg-error-cat'));

Then when you do:

JLog::add('an error to display', JLog::ERROR, 'msg-error-cat');

you will get the message copied to the message bar. Note that Joomla core code sets up logging to the messagequeue for category 'jerror', so that if you use this category in your log messages, you will get the message displayed on the message bar. For example:

JLog::add('error copied to message bar', JLog::Error, 'jerror');

will result in the message being shown in the Joomla message area, even though you haven't explicitly set up a logger to log there.

PSR-3 Logger

Since version 3.8 Joomla incorporates a logger which adheres to the PSR-3 Logger Interface. This enables libraries which follow this standard recommendation to integrate with the Joomla logging system. To use this, first do:

use Joomla\CMS\Log\Log;
$psr3Logger = Log::createDelegatedLogger();

This returns an object on which you have available the methods of the PSR-3 LoggerInterface, for example:

$psr3Logger->critical("critical error text", array("category" => "my-critical-category"));

The default Joomla loggers process only the "category" and "date" elements of the context associative array (parameter 2), mapping the values of these elements to the corresponding column in your log file.

Exceptions

JLog::add() will throw an exception if it can't write to the log file. To avoid this, you'd have to either wrap the call in another function, or implement your own logger class and then include it with:

JLog::addLogger(
    array(
         // Use mycustomlogger.
         'logger' => 'mycustomlogger',
         'text_file' => 'com_helloworld.errors.php'
    ),
    JLog::ALL,
    array('com_helloworld')
);

Further Reading

Joomla logging should be used in tandem with PHP exceptions, not as a replacement. See J2.5:Exceptions_and_Logging_in_Joomla_Platform_11.1_and_Joomla_2.5 for backstory on this class and how it arose from the old Joomla PHP4 compatible error classes.

星期三, 25 12月 2019 08:30

JHtml的用法

JHtml的源文件在:/libraries/src/HTML/HTMLHelper.php。

1、JHtml::_('behavior.tabstate')会调用/libraries/cms/html中的behavior.php文件中的JHtmlBehavior类的tabstate方法。
2、像JHtml::_('scrpit'),JHtml::_('date'),JHtml::_('stylesheet'),,没有点的,会之间调用/libraries/src/HTML/HTMLHelper.php的JHtml相应的方法。
/libraries/classmap.php中通过JLoader,预先加载了很多类,并定义了别用。
通过搜索命名空间可以找到每个具体类的位置。
比如JFactory对应的命名空间Joomla\\CMS,可以找到JFactory类的文件在/libraries/src/Factory.php文件
实际上这些预加载的大部分类都是在/libraries/src/中。


<?php
/**
* @package Joomla.Libraries
*
* @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/

// No direct access.
defined('_JEXEC') or die;

JLoader::registerAlias('JRegistry', '\\Joomla\\Registry\\Registry', '5.0');
JLoader::registerAlias('JRegistryFormat', '\\Joomla\\Registry\\AbstractRegistryFormat', '4.0');
JLoader::registerAlias('JRegistryFormatIni', '\\Joomla\\Registry\\Format\\Ini', '5.0');
JLoader::registerAlias('JRegistryFormatJson', '\\Joomla\\Registry\\Format\\Json', '5.0');
JLoader::registerAlias('JRegistryFormatPhp', '\\Joomla\\Registry\\Format\\Php', '5.0');
JLoader::registerAlias('JRegistryFormatXml', '\\Joomla\\Registry\\Format\\Xml', '5.0');
JLoader::registerAlias('JStringInflector', '\\Joomla\\String\\Inflector', '5.0');
JLoader::registerAlias('JStringNormalise', '\\Joomla\\String\\Normalise', '5.0');
JLoader::registerAlias('JData', '\\Joomla\\Data\\DataObject', '5.0');
JLoader::registerAlias('JDataSet', '\\Joomla\\Data\\DataSet', '5.0');
JLoader::registerAlias('JDataDumpable', '\\Joomla\\Data\\DumpableInterface', '5.0');

JLoader::registerAlias('JApplicationAdministrator', '\\Joomla\\CMS\\Application\\AdministratorApplication', '5.0');
JLoader::registerAlias('JApplicationHelper', '\\Joomla\\CMS\\Application\\ApplicationHelper', '5.0');
JLoader::registerAlias('JApplicationBase', '\\Joomla\\CMS\\Application\\BaseApplication', '5.0');
JLoader::registerAlias('JApplicationCli', '\\Joomla\\CMS\\Application\\CliApplication', '5.0');
JLoader::registerAlias('JApplicationCms', '\\Joomla\\CMS\\Application\\CMSApplication', '5.0');
JLoader::registerAlias('JApplicationDaemon', '\\Joomla\\CMS\\Application\\DaemonApplication', '5.0');
JLoader::registerAlias('JApplicationSite', '\\Joomla\\CMS\\Application\\SiteApplication', '5.0');
JLoader::registerAlias('JApplicationWeb', '\\Joomla\\CMS\\Application\\WebApplication', '5.0');
JLoader::registerAlias('JApplicationWebClient', '\\Joomla\\Application\\Web\\WebClient', '5.0');
JLoader::registerAlias('JDaemon', '\\Joomla\\CMS\\Application\\DaemonApplication', '5.0');
JLoader::registerAlias('JCli', '\\Joomla\\CMS\\Application\\CliApplication', '5.0');
JLoader::registerAlias('JWeb', '\\Joomla\\CMS\\Application\\WebApplication', '4.0');
JLoader::registerAlias('JWebClient', '\\Joomla\\Application\\Web\\WebClient', '4.0');

JLoader::registerAlias('JModelAdmin', '\\Joomla\\CMS\\MVC\\Model\\AdminModel', '5.0');
JLoader::registerAlias('JModelForm', '\\Joomla\\CMS\\MVC\\Model\\FormModel', '5.0');
JLoader::registerAlias('JModelItem', '\\Joomla\\CMS\\MVC\\Model\\ItemModel', '5.0');
JLoader::registerAlias('JModelList', '\\Joomla\\CMS\\MVC\\Model\\ListModel', '5.0');
JLoader::registerAlias('JModelLegacy', '\\Joomla\\CMS\\MVC\\Model\\BaseDatabaseModel', '5.0');
JLoader::registerAlias('JViewCategories', '\\Joomla\\CMS\\MVC\\View\\CategoriesView', '5.0');
JLoader::registerAlias('JViewCategory', '\\Joomla\\CMS\\MVC\\View\\CategoryView', '5.0');
JLoader::registerAlias('JViewCategoryfeed', '\\Joomla\\CMS\\MVC\\View\\CategoryFeedView', '5.0');
JLoader::registerAlias('JViewLegacy', '\\Joomla\\CMS\\MVC\\View\\HtmlView', '5.0');
JLoader::registerAlias('JControllerAdmin', '\\Joomla\\CMS\\MVC\\Controller\\AdminController', '5.0');
JLoader::registerAlias('JControllerLegacy', '\\Joomla\\CMS\\MVC\\Controller\\BaseController', '5.0');
JLoader::registerAlias('JControllerForm', '\\Joomla\\CMS\\MVC\\Controller\\FormController', '5.0');
JLoader::registerAlias('JTableInterface', '\\Joomla\\CMS\\Table\\TableInterface', '5.0');
JLoader::registerAlias('JTable', '\\Joomla\\CMS\\Table\\Table', '5.0');
JLoader::registerAlias('JTableNested', '\\Joomla\\CMS\\Table\\Nested', '5.0');
JLoader::registerAlias('JTableAsset', '\\Joomla\\CMS\\Table\\Asset', '5.0');
JLoader::registerAlias('JTableExtension', '\\Joomla\\CMS\\Table\\Extension', '5.0');
JLoader::registerAlias('JTableLanguage', '\\Joomla\\CMS\\Table\\Language', '5.0');
JLoader::registerAlias('JTableUpdate', '\\Joomla\\CMS\\Table\\Update', '5.0');
JLoader::registerAlias('JTableUpdatesite', '\\Joomla\\CMS\\Table\\UpdateSite', '5.0');
JLoader::registerAlias('JTableUser', '\\Joomla\\CMS\\Table\\User', '5.0');
JLoader::registerAlias('JTableUsergroup', '\\Joomla\\CMS\\Table\\Usergroup', '5.0');
JLoader::registerAlias('JTableViewlevel', '\\Joomla\\CMS\\Table\\ViewLevel', '5.0');
JLoader::registerAlias('JTableContenthistory', '\\Joomla\\CMS\\Table\\ContentHistory', '5.0');
JLoader::registerAlias('JTableContenttype', '\\Joomla\\CMS\\Table\\ContentType', '5.0');
JLoader::registerAlias('JTableCorecontent', '\\Joomla\\CMS\\Table\\CoreContent', '5.0');
JLoader::registerAlias('JTableUcm', '\\Joomla\\CMS\\Table\\Ucm', '5.0');
JLoader::registerAlias('JTableCategory', '\\Joomla\\CMS\\Table\\Category', '5.0');
JLoader::registerAlias('JTableContent', '\\Joomla\\CMS\\Table\\Content', '5.0');
JLoader::registerAlias('JTableMenu', '\\Joomla\\CMS\\Table\\Menu', '5.0');
JLoader::registerAlias('JTableMenuType', '\\Joomla\\CMS\\Table\\MenuType', '5.0');
JLoader::registerAlias('JTableModule', '\\Joomla\\CMS\\Table\\Module', '5.0');
JLoader::registerAlias('JTableObserver', '\\Joomla\\CMS\\Table\\Observer\\AbstractObserver', '5.0');
JLoader::registerAlias('JTableObserverContenthistory', '\\Joomla\\CMS\\Table\\Observer\\ContentHistory', '5.0');
JLoader::registerAlias('JTableObserverTags', '\\Joomla\\CMS\\Table\\Observer\\Tags', '5.0');

JLoader::registerAlias('JAccess', '\\Joomla\\CMS\\Access\\Access', '5.0');
JLoader::registerAlias('JAccessRule', '\\Joomla\\CMS\\Access\\Rule', '5.0');
JLoader::registerAlias('JAccessRules', '\\Joomla\\CMS\\Access\\Rules', '5.0');
JLoader::registerAlias('JAccessWrapperAccess', '\\Joomla\\CMS\\Access\\Wrapper\\Access', '4.0');
JLoader::registerAlias('JAccessExceptionNotallowed', '\\Joomla\\CMS\\Access\\Exception\\NotAllowed', '5.0');
JLoader::registerAlias('JRule', '\\Joomla\\CMS\\Access\\Rule', '5.0');
JLoader::registerAlias('JRules', '\\Joomla\\CMS\\Access\\Rules', '5.0');

JLoader::registerAlias('JHelp', '\\Joomla\\CMS\\Help\\Help', '5.0');
JLoader::registerAlias('JCaptcha', '\\Joomla\\CMS\\Captcha\\Captcha', '5.0');

JLoader::registerAlias('JLanguageAssociations', '\\Joomla\\CMS\\Language\\Associations', '5.0');
JLoader::registerAlias('JLanguage', '\\Joomla\\CMS\\Language\\Language', '5.0');
JLoader::registerAlias('JLanguageHelper', '\\Joomla\\CMS\\Language\\LanguageHelper', '5.0');
JLoader::registerAlias('JLanguageStemmer', '\\Joomla\\CMS\\Language\\LanguageStemmer', '5.0');
JLoader::registerAlias('JLanguageMultilang', '\\Joomla\\CMS\\Language\\Multilanguage', '5.0');
JLoader::registerAlias('JText', '\\Joomla\\CMS\\Language\\Text', '5.0');
JLoader::registerAlias('JLanguageTransliterate', '\\Joomla\\CMS\\Language\\Transliterate', '5.0');
JLoader::registerAlias('JLanguageStemmerPorteren', '\\Joomla\\CMS\\Language\\Stemmer\\Porteren', '5.0');
JLoader::registerAlias('JLanguageWrapperText', '\\Joomla\\CMS\\Language\\Wrapper\\JTextWrapper', '4.0');
JLoader::registerAlias('JLanguageWrapperHelper', '\\Joomla\\CMS\\Language\\Wrapper\\LanguageHelperWrapper', '4.0');
JLoader::registerAlias('JLanguageWrapperTransliterate', '\\Joomla\\CMS\\Language\\Wrapper\\TransliterateWrapper', '4.0');

JLoader::registerAlias('JComponentHelper', '\\Joomla\\CMS\\Component\\ComponentHelper', '5.0');
JLoader::registerAlias('JComponentRecord', '\\Joomla\\CMS\\Component\\ComponentRecord', '5.0');
JLoader::registerAlias('JComponentExceptionMissing', '\\Joomla\\CMS\\Component\\Exception\\MissingComponentException', '5.0');
JLoader::registerAlias('JComponentRouterBase', '\\Joomla\\CMS\\Component\\Router\\RouterBase', '5.0');
JLoader::registerAlias('JComponentRouterInterface', '\\Joomla\\CMS\\Component\\Router\\RouterInterface', '5.0');
JLoader::registerAlias('JComponentRouterLegacy', '\\Joomla\\CMS\\Component\\Router\\RouterLegacy', '5.0');
JLoader::registerAlias('JComponentRouterView', '\\Joomla\\CMS\\Component\\Router\\RouterView', '5.0');
JLoader::registerAlias('JComponentRouterViewconfiguration', '\\Joomla\\CMS\\Component\\Router\\RouterViewConfiguration', '5.0');
JLoader::registerAlias('JComponentRouterRulesMenu', '\\Joomla\\CMS\\Component\\Router\\Rules\\MenuRules', '5.0');
JLoader::registerAlias('JComponentRouterRulesNomenu', '\\Joomla\\CMS\\Component\\Router\\Rules\\NomenuRules', '5.0');
JLoader::registerAlias('JComponentRouterRulesInterface', '\\Joomla\\CMS\\Component\\Router\\Rules\\RulesInterface', '5.0');
JLoader::registerAlias('JComponentRouterRulesStandard', '\\Joomla\\CMS\\Component\\Router\\Rules\\StandardRules', '5.0');

JLoader::registerAlias('JEditor', '\\Joomla\\CMS\\Editor\\Editor', '5.0');

JLoader::registerAlias('JErrorPage', '\\Joomla\\CMS\\Exception\\ExceptionHandler', '5.0');

JLoader::registerAlias('JAuthenticationHelper', '\\Joomla\\CMS\\Helper\\AuthenticationHelper', '5.0');
JLoader::registerAlias('JHelper', '\\Joomla\\CMS\\Helper\\CMSHelper', '5.0');
JLoader::registerAlias('JHelperContent', '\\Joomla\\CMS\\Helper\\ContentHelper', '5.0');
JLoader::registerAlias('JHelperContenthistory', '\\Joomla\\CMS\\Helper\\ContentHistoryHelper', '5.0');
JLoader::registerAlias('JLibraryHelper', '\\Joomla\\CMS\\Helper\\LibraryHelper', '5.0');
JLoader::registerAlias('JHelperMedia', '\\Joomla\\CMS\\Helper\\MediaHelper', '5.0');
JLoader::registerAlias('JModuleHelper', '\\Joomla\\CMS\\Helper\\ModuleHelper', '5.0');
JLoader::registerAlias('JHelperRoute', '\\Joomla\\CMS\\Helper\\RouteHelper', '5.0');
JLoader::registerAlias('JSearchHelper', '\\Joomla\\CMS\\Helper\\SearchHelper', '5.0');
JLoader::registerAlias('JHelperTags', '\\Joomla\\CMS\\Helper\\TagsHelper', '5.0');
JLoader::registerAlias('JHelperUsergroups', '\\Joomla\\CMS\\Helper\\UserGroupsHelper', '5.0');

JLoader::registerAlias('JLayoutBase', '\\Joomla\\CMS\\Layout\\BaseLayout', '5.0');
JLoader::registerAlias('JLayoutFile', '\\Joomla\\CMS\\Layout\\FileLayout', '5.0');
JLoader::registerAlias('JLayoutHelper', '\\Joomla\\CMS\\Layout\\LayoutHelper', '5.0');
JLoader::registerAlias('JLayout', '\\Joomla\\CMS\\Layout\\LayoutInterface', '5.0');

JLoader::registerAlias('JResponseJson', '\\Joomla\\CMS\\Response\\JsonResponse', '5.0');

JLoader::registerAlias('JPlugin', '\\Joomla\\CMS\\Plugin\\CMSPlugin', '5.0');
JLoader::registerAlias('JPluginHelper', '\\Joomla\\CMS\\Plugin\\PluginHelper', '5.0');

JLoader::registerAlias('JMenu', '\\Joomla\\CMS\\Menu\\AbstractMenu', '5.0');
JLoader::registerAlias('JMenuAdministrator', '\\Joomla\\CMS\\Menu\\AdministratorMenu', '5.0');
JLoader::registerAlias('JMenuItem', '\\Joomla\\CMS\\Menu\\MenuItem', '5.0');
JLoader::registerAlias('JMenuSite', '\\Joomla\\CMS\\Menu\\SiteMenu', '5.0');

JLoader::registerAlias('JPagination', '\\Joomla\\CMS\\Pagination\\Pagination', '5.0');
JLoader::registerAlias('JPaginationObject', '\\Joomla\\CMS\\Pagination\\PaginationObject', '5.0');

JLoader::registerAlias('JPathway', '\\Joomla\\CMS\\Pathway\\Pathway', '5.0');
JLoader::registerAlias('JPathwaySite', '\\Joomla\\CMS\\Pathway\\SitePathway', '5.0');

JLoader::registerAlias('JSchemaChangeitem', '\\Joomla\\CMS\\Schema\\ChangeItem', '5.0');
JLoader::registerAlias('JSchemaChangeset', '\\Joomla\\CMS\\Schema\\ChangeSet', '5.0');
JLoader::registerAlias('JSchemaChangeitemMysql', '\\Joomla\\CMS\\Schema\\ChangeItem\\MysqlChangeItem', '5.0');
JLoader::registerAlias('JSchemaChangeitemPostgresql', '\\Joomla\\CMS\\Schema\\ChangeItem\\PostgresqlChangeItem', '5.0');
JLoader::registerAlias('JSchemaChangeitemSqlsrv', '\\Joomla\\CMS\\Schema\\ChangeItem\\SqlsrvChangeItem', '5.0');

JLoader::registerAlias('JUcm', '\\Joomla\\CMS\\UCM\\UCM', '5.0');
JLoader::registerAlias('JUcmBase', '\\Joomla\\CMS\\UCM\\UCMBase', '5.0');
JLoader::registerAlias('JUcmContent', '\\Joomla\\CMS\\UCM\\UCMContent', '5.0');
JLoader::registerAlias('JUcmType', '\\Joomla\\CMS\\UCM\\UCMType', '5.0');

JLoader::registerAlias('JToolbar', '\\Joomla\\CMS\\Toolbar\\Toolbar', '5.0');
JLoader::registerAlias('JToolbarButton', '\\Joomla\\CMS\\Toolbar\\ToolbarButton', '5.0');
JLoader::registerAlias('JToolbarButtonConfirm', '\\Joomla\\CMS\\Toolbar\\Button\\ConfirmButton', '5.0');
JLoader::registerAlias('JToolbarButtonCustom', '\\Joomla\\CMS\\Toolbar\\Button\\CustomButton', '5.0');
JLoader::registerAlias('JToolbarButtonHelp', '\\Joomla\\CMS\\Toolbar\\Button\\HelpButton', '5.0');
JLoader::registerAlias('JToolbarButtonLink', '\\Joomla\\CMS\\Toolbar\\Button\\LinkButton', '5.0');
JLoader::registerAlias('JToolbarButtonPopup', '\\Joomla\\CMS\\Toolbar\\Button\\PopupButton', '5.0');
JLoader::registerAlias('JToolbarButtonSeparator', '\\Joomla\\CMS\\Toolbar\\Button\\SeparatorButton', '5.0');
JLoader::registerAlias('JToolbarButtonSlider', '\\Joomla\\CMS\\Toolbar\\Button\\SliderButton', '5.0');
JLoader::registerAlias('JToolbarButtonStandard', '\\Joomla\\CMS\\Toolbar\\Button\\StandardButton', '5.0');
JLoader::registerAlias('JButton', '\\Joomla\\CMS\\Toolbar\\ToolbarButton', '5.0');

JLoader::registerAlias('JVersion', '\\Joomla\\CMS\\Version', '5.0');

JLoader::registerAlias('JAuthentication', '\\Joomla\\CMS\\Authentication\\Authentication', '5.0');
JLoader::registerAlias('JAuthenticationResponse', '\\Joomla\\CMS\\Authentication\\AuthenticationResponse', '5.0');

JLoader::registerAlias('JBrowser', '\\Joomla\\CMS\\Environment\\Browser', '5.0');

JLoader::registerAlias('JAssociationExtensionInterface', '\\Joomla\\CMS\\Association\\AssociationExtensionInterface', '5.0');
JLoader::registerAlias('JAssociationExtensionHelper', '\\Joomla\\CMS\\Association\\AssociationExtensionHelper', '5.0');

JLoader::registerAlias('JDocument', '\\Joomla\\CMS\\Document\\Document', '5.0');
JLoader::registerAlias('JDocumentError', '\\Joomla\\CMS\\Document\\ErrorDocument', '5.0');
JLoader::registerAlias('JDocumentFeed', '\\Joomla\\CMS\\Document\\FeedDocument', '5.0');
JLoader::registerAlias('JDocumentHtml', '\\Joomla\\CMS\\Document\\HtmlDocument', '5.0');
JLoader::registerAlias('JDocumentImage', '\\Joomla\\CMS\\Document\\ImageDocument', '5.0');
JLoader::registerAlias('JDocumentJson', '\\Joomla\\CMS\\Document\\JsonDocument', '5.0');
JLoader::registerAlias('JDocumentOpensearch', '\\Joomla\\CMS\\Document\\OpensearchDocument', '5.0');
JLoader::registerAlias('JDocumentRaw', '\\Joomla\\CMS\\Document\\RawDocument', '5.0');
JLoader::registerAlias('JDocumentRenderer', '\\Joomla\\CMS\\Document\\DocumentRenderer', '5.0');
JLoader::registerAlias('JDocumentXml', '\\Joomla\\CMS\\Document\\XmlDocument', '5.0');
JLoader::registerAlias('JDocumentRendererFeedAtom', '\\Joomla\\CMS\\Document\\Renderer\\Feed\\AtomRenderer', '5.0');
JLoader::registerAlias('JDocumentRendererFeedRss', '\\Joomla\\CMS\\Document\\Renderer\\Feed\\RssRenderer', '5.0');
JLoader::registerAlias('JDocumentRendererHtmlComponent', '\\Joomla\\CMS\\Document\\Renderer\\Html\\ComponentRenderer', '5.0');
JLoader::registerAlias('JDocumentRendererHtmlHead', '\\Joomla\\CMS\\Document\\Renderer\\Html\\HeadRenderer', '5.0');
JLoader::registerAlias('JDocumentRendererHtmlMessage', '\\Joomla\\CMS\\Document\\Renderer\\Html\\MessageRenderer', '5.0');
JLoader::registerAlias('JDocumentRendererHtmlModule', '\\Joomla\\CMS\\Document\\Renderer\\Html\\ModuleRenderer', '5.0');
JLoader::registerAlias('JDocumentRendererHtmlModules', '\\Joomla\\CMS\\Document\\Renderer\\Html\\ModulesRenderer', '5.0');
JLoader::registerAlias('JDocumentRendererAtom', '\\Joomla\\CMS\\Document\\Renderer\\Feed\\AtomRenderer', '4.0');
JLoader::registerAlias('JDocumentRendererRSS', '\\Joomla\\CMS\\Document\\Renderer\\Feed\\RssRenderer', '4.0');
JLoader::registerAlias('JDocumentRendererComponent', '\\Joomla\\CMS\\Document\\Renderer\\Html\\ComponentRenderer', '4.0');
JLoader::registerAlias('JDocumentRendererHead', '\\Joomla\\CMS\\Document\\Renderer\\Html\\HeadRenderer', '4.0');
JLoader::registerAlias('JDocumentRendererMessage', '\\Joomla\\CMS\\Document\\Renderer\\Html\\MessageRenderer', '4.0');
JLoader::registerAlias('JDocumentRendererModule', '\\Joomla\\CMS\\Document\\Renderer\\Html\\ModuleRenderer', '4.0');
JLoader::registerAlias('JDocumentRendererModules', '\\Joomla\\CMS\\Document\\Renderer\\Html\\ModulesRenderer', '4.0');
JLoader::registerAlias('JFeedEnclosure', '\\Joomla\\CMS\\Document\\Feed\\FeedEnclosure', '5.0');
JLoader::registerAlias('JFeedImage', '\\Joomla\\CMS\\Document\\Feed\\FeedImage', '5.0');
JLoader::registerAlias('JFeedItem', '\\Joomla\\CMS\\Document\\Feed\\FeedItem', '5.0');
JLoader::registerAlias('JOpenSearchImage', '\\Joomla\\CMS\\Document\\Opensearch\\OpensearchImage', '5.0');
JLoader::registerAlias('JOpenSearchUrl', '\\Joomla\\CMS\\Document\\Opensearch\\OpensearchUrl', '5.0');

JLoader::registerAlias('JFilterInput', '\\Joomla\\CMS\\Filter\\InputFilter', '5.0');
JLoader::registerAlias('JFilterOutput', '\\Joomla\\CMS\\Filter\\OutputFilter', '5.0');
JLoader::registerAlias('JFilterWrapperOutput', '\\Joomla\\CMS\\Filter\\Wrapper\\OutputFilterWrapper', '4.0');

JLoader::registerAlias('JHttp', '\\Joomla\\CMS\\Http\\Http', '5.0');
JLoader::registerAlias('JHttpFactory', '\\Joomla\\CMS\\Http\\HttpFactory', '5.0');
JLoader::registerAlias('JHttpResponse', '\\Joomla\\CMS\\Http\\Response', '5.0');
JLoader::registerAlias('JHttpTransport', '\\Joomla\\CMS\\Http\\TransportInterface', '5.0');
JLoader::registerAlias('JHttpTransportCurl', '\\Joomla\\CMS\\Http\\Transport\\CurlTransport', '5.0');
JLoader::registerAlias('JHttpTransportSocket', '\\Joomla\\CMS\\Http\\Transport\\SocketTransport', '5.0');
JLoader::registerAlias('JHttpTransportStream', '\\Joomla\\CMS\\Http\\Transport\\StreamTransport', '5.0');
JLoader::registerAlias('JHttpWrapperFactory', '\\Joomla\\CMS\\Http\\Wrapper\\FactoryWrapper', '4.0');

JLoader::registerAlias('JInstaller', '\\Joomla\\CMS\\Installer\\Installer', '5.0');
JLoader::registerAlias('JInstallerAdapter', '\\Joomla\\CMS\\Installer\\InstallerAdapter', '5.0');
JLoader::registerAlias('JInstallerExtension', '\\Joomla\\CMS\\Installer\\InstallerExtension', '5.0');
JLoader::registerAlias('JExtension', '\\Joomla\\CMS\\Installer\\InstallerExtension', '5.0');
JLoader::registerAlias('JInstallerHelper', '\\Joomla\\CMS\\Installer\\InstallerHelper', '5.0');
JLoader::registerAlias('JInstallerScript', '\\Joomla\\CMS\\Installer\\InstallerScript', '5.0');
JLoader::registerAlias('JInstallerManifest', '\\Joomla\\CMS\\Installer\\Manifest', '5.0');
JLoader::registerAlias('JInstallerAdapterComponent', '\\Joomla\\CMS\\Installer\\Adapter\\ComponentAdapter', '5.0');
JLoader::registerAlias('JInstallerComponent', '\\Joomla\\CMS\\Installer\\Adapter\\ComponentAdapter', '5.0');
JLoader::registerAlias('JInstallerAdapterFile', '\\Joomla\\CMS\\Installer\\Adapter\\FileAdapter', '5.0');
JLoader::registerAlias('JInstallerFile', '\\Joomla\\CMS\\Installer\\Adapter\\FileAdapter', '5.0');
JLoader::registerAlias('JInstallerAdapterLanguage', '\\Joomla\\CMS\\Installer\\Adapter\\LanguageAdapter', '5.0');
JLoader::registerAlias('JInstallerLanguage', '\\Joomla\\CMS\\Installer\\Adapter\\LanguageAdapter', '5.0');
JLoader::registerAlias('JInstallerAdapterLibrary', '\\Joomla\\CMS\\Installer\\Adapter\\LibraryAdapter', '5.0');
JLoader::registerAlias('JInstallerLibrary', '\\Joomla\\CMS\\Installer\\Adapter\\LibraryAdapter', '5.0');
JLoader::registerAlias('JInstallerAdapterModule', '\\Joomla\\CMS\\Installer\\Adapter\\ModuleAdapter', '5.0');
JLoader::registerAlias('JInstallerModule', '\\Joomla\\CMS\\Installer\\Adapter\\ModuleAdapter', '5.0');
JLoader::registerAlias('JInstallerAdapterPackage', '\\Joomla\\CMS\\Installer\\Adapter\\PackageAdapter', '5.0');
JLoader::registerAlias('JInstallerPackage', '\\Joomla\\CMS\\Installer\\Adapter\\PackageAdapter', '5.0');
JLoader::registerAlias('JInstallerAdapterPlugin', '\\Joomla\\CMS\\Installer\\Adapter\\PluginAdapter', '5.0');
JLoader::registerAlias('JInstallerPlugin', '\\Joomla\\CMS\\Installer\\Adapter\\PluginAdapter', '5.0');
JLoader::registerAlias('JInstallerAdapterTemplate', '\\Joomla\\CMS\\Installer\\Adapter\\TemplateAdapter', '5.0');
JLoader::registerAlias('JInstallerTemplate', '\\Joomla\\CMS\\Installer\\Adapter\\TemplateAdapter', '5.0');
JLoader::registerAlias('JInstallerManifestLibrary', '\\Joomla\\CMS\\Installer\\Manifest\\LibraryManifest', '5.0');
JLoader::registerAlias('JInstallerManifestPackage', '\\Joomla\\CMS\\Installer\\Manifest\\PackageManifest', '5.0');

JLoader::registerAlias('JRouterAdministrator', '\\Joomla\\CMS\\Router\\AdministratorRouter', '5.0');
JLoader::registerAlias('JRoute', '\\Joomla\\CMS\\Router\\Route', '5.0');
JLoader::registerAlias('JRouter', '\\Joomla\\CMS\\Router\\Router', '5.0');
JLoader::registerAlias('JRouterSite', '\\Joomla\\CMS\\Router\\SiteRouter', '5.0');

JLoader::registerAlias('JCategories', '\\Joomla\\CMS\\Categories\\Categories', '5.0');
JLoader::registerAlias('JCategoryNode', '\\Joomla\\CMS\\Categories\\CategoryNode', '5.0');

JLoader::registerAlias('JDate', '\\Joomla\\CMS\\Date\\Date', '5.0');

JLoader::registerAlias('JLog', '\\Joomla\\CMS\\Log\\Log', '5.0');
JLoader::registerAlias('JLogEntry', '\\Joomla\\CMS\\Log\\LogEntry', '5.0');
JLoader::registerAlias('JLogLogger', '\\Joomla\\CMS\\Log\\Logger', '5.0');
JLoader::registerAlias('JLogger', '\\Joomla\\CMS\\Log\\Logger', '5.0');
JLoader::registerAlias('JLogLoggerCallback', '\\Joomla\\CMS\\Log\\Logger\\CallbackLogger', '5.0');
JLoader::registerAlias('JLogLoggerDatabase', '\\Joomla\\CMS\\Log\\Logger\\DatabaseLogger', '5.0');
JLoader::registerAlias('JLogLoggerEcho', '\\Joomla\\CMS\\Log\\Logger\\EchoLogger', '5.0');
JLoader::registerAlias('JLogLoggerFormattedtext', '\\Joomla\\CMS\\Log\\Logger\\FormattedtextLogger', '5.0');
JLoader::registerAlias('JLogLoggerMessagequeue', '\\Joomla\\CMS\\Log\\Logger\\MessagequeueLogger', '5.0');
JLoader::registerAlias('JLogLoggerSyslog', '\\Joomla\\CMS\\Log\\Logger\\SyslogLogger', '5.0');
JLoader::registerAlias('JLogLoggerW3c', '\\Joomla\\CMS\\Log\\Logger\\W3cLogger', '5.0');

JLoader::registerAlias('JProfiler', '\\Joomla\\CMS\\Profiler\\Profiler', '5.0');

JLoader::registerAlias('JUri', '\\Joomla\\CMS\\Uri\\Uri', '5.0');

JLoader::registerAlias('JCache', '\\Joomla\\CMS\\Cache\\Cache', '5.0');
JLoader::registerAlias('JCacheController', '\\Joomla\\CMS\\Cache\\CacheController', '5.0');
JLoader::registerAlias('JCacheStorage', '\\Joomla\\CMS\\Cache\\CacheStorage', '5.0');
JLoader::registerAlias('JCacheControllerCallback', '\\Joomla\\CMS\\Cache\\Controller\\CallbackController', '5.0');
JLoader::registerAlias('JCacheControllerOutput', '\\Joomla\\CMS\\Cache\\Controller\\OutputController', '5.0');
JLoader::registerAlias('JCacheControllerPage', '\\Joomla\\CMS\\Cache\\Controller\\PageController', '5.0');
JLoader::registerAlias('JCacheControllerView', '\\Joomla\\CMS\\Cache\\Controller\\ViewController', '5.0');
JLoader::registerAlias('JCacheStorageApc', '\\Joomla\\CMS\\Cache\\Storage\\ApcStorage', '5.0');
JLoader::registerAlias('JCacheStorageApcu', '\\Joomla\\CMS\\Cache\\Storage\\ApcuStorage', '5.0');
JLoader::registerAlias('JCacheStorageHelper', '\\Joomla\\CMS\\Cache\\Storage\\CacheStorageHelper', '5.0');
JLoader::registerAlias('JCacheStorageCachelite', '\\Joomla\\CMS\\Cache\\Storage\\CacheliteStorage', '4.0');
JLoader::registerAlias('JCacheStorageFile', '\\Joomla\\CMS\\Cache\\Storage\\FileStorage', '5.0');
JLoader::registerAlias('JCacheStorageMemcached', '\\Joomla\\CMS\\Cache\\Storage\\MemcachedStorage', '5.0');
JLoader::registerAlias('JCacheStorageMemcache', '\\Joomla\\CMS\\Cache\\Storage\\MemcacheStorage', '5.0');
JLoader::registerAlias('JCacheStorageRedis', '\\Joomla\\CMS\\Cache\\Storage\\RedisStorage', '5.0');
JLoader::registerAlias('JCacheStorageWincache', '\\Joomla\\CMS\\Cache\\Storage\\WincacheStorage', '5.0');
JLoader::registerAlias('JCacheStorageXcache', '\\Joomla\\CMS\\Cache\\Storage\\XcacheStorage', '5.0');
JLoader::registerAlias('JCacheException', '\\Joomla\\CMS\\Cache\\Exception\\CacheExceptionInterface', '5.0');
JLoader::registerAlias('JCacheExceptionConnecting', '\\Joomla\\CMS\\Cache\\Exception\\CacheConnectingException', '5.0');
JLoader::registerAlias('JCacheExceptionUnsupported', '\\Joomla\\CMS\\Cache\\Exception\\UnsupportedCacheException', '5.0');

JLoader::registerAlias('JSession', '\\Joomla\\CMS\\Session\\Session', '5.0');
JLoader::registerAlias('JSessionExceptionUnsupported', '\\Joomla\\CMS\\Session\\Exception\\UnsupportedStorageException', '5.0');

JLoader::registerAlias('JUser', '\\Joomla\\CMS\\User\\User', '5.0');
JLoader::registerAlias('JUserHelper', '\\Joomla\\CMS\\User\\UserHelper', '5.0');
JLoader::registerAlias('JUserWrapperHelper', '\\Joomla\\CMS\\User\\UserWrapper', '4.0');

JLoader::registerAlias('JForm', '\\Joomla\\CMS\\Form\\Form', '5.0');
JLoader::registerAlias('JFormField', '\\Joomla\\CMS\\Form\\FormField', '5.0');
JLoader::registerAlias('JFormHelper', '\\Joomla\\CMS\\Form\\FormHelper', '5.0');
JLoader::registerAlias('JFormRule', '\\Joomla\\CMS\\Form\\FormRule', '5.0');
JLoader::registerAlias('JFormWrapper', '\\Joomla\\CMS\\Form\\FormWrapper', '4.0');
JLoader::registerAlias('JFormFieldAuthor', '\\Joomla\\CMS\\Form\\Field\\AuthorField', '5.0');
JLoader::registerAlias('JFormFieldCaptcha', '\\Joomla\\CMS\\Form\\Field\\CaptchaField', '5.0');
JLoader::registerAlias('JFormFieldChromeStyle', '\\Joomla\\CMS\\Form\\Field\\ChromestyleField', '5.0');
JLoader::registerAlias('JFormFieldContenthistory', '\\Joomla\\CMS\\Form\\Field\\ContenthistoryField', '5.0');
JLoader::registerAlias('JFormFieldContentlanguage', '\\Joomla\\CMS\\Form\\Field\\ContentlanguageField', '5.0');
JLoader::registerAlias('JFormFieldContenttype', '\\Joomla\\CMS\\Form\\Field\\ContenttypeField', '5.0');
JLoader::registerAlias('JFormFieldEditor', '\\Joomla\\CMS\\Form\\Field\\EditorField', '5.0');
JLoader::registerAlias('JFormFieldFrontend_Language', '\\Joomla\\CMS\\Form\\Field\\FrontendlanguageField', '5.0');
JLoader::registerAlias('JFormFieldHeadertag', '\\Joomla\\CMS\\Form\\Field\\HeadertagField', '5.0');
JLoader::registerAlias('JFormFieldHelpsite', '\\Joomla\\CMS\\Form\\Field\\HelpsiteField', '5.0');
JLoader::registerAlias('JFormFieldLastvisitDateRange', '\\Joomla\\CMS\\Form\\Field\\LastvisitdaterangeField', '5.0');
JLoader::registerAlias('JFormFieldLimitbox', '\\Joomla\\CMS\\Form\\Field\\LimitboxField', '5.0');
JLoader::registerAlias('JFormFieldMedia', '\\Joomla\\CMS\\Form\\Field\\MediaField', '5.0');
JLoader::registerAlias('JFormFieldMenu', '\\Joomla\\CMS\\Form\\Field\\MenuField', '5.0');
JLoader::registerAlias('JFormFieldMenuitem', '\\Joomla\\CMS\\Form\\Field\\MenuitemField', '5.0');
JLoader::registerAlias('JFormFieldModuleOrder', '\\Joomla\\CMS\\Form\\Field\\ModuleorderField', '5.0');
JLoader::registerAlias('JFormFieldModulePosition', '\\Joomla\\CMS\\Form\\Field\\ModulepositionField', '5.0');
JLoader::registerAlias('JFormFieldModuletag', '\\Joomla\\CMS\\Form\\Field\\ModuletagField', '5.0');
JLoader::registerAlias('JFormFieldOrdering', '\\Joomla\\CMS\\Form\\Field\\OrderingField', '5.0');
JLoader::registerAlias('JFormFieldPlugin_Status', '\\Joomla\\CMS\\Form\\Field\\PluginstatusField', '5.0');
JLoader::registerAlias('JFormFieldRedirect_Status', '\\Joomla\\CMS\\Form\\Field\\RedirectStatusField', '5.0');
JLoader::registerAlias('JFormFieldRegistrationDateRange', '\\Joomla\\CMS\\Form\\Field\\RegistrationdaterangeField', '5.0');
JLoader::registerAlias('JFormFieldStatus', '\\Joomla\\CMS\\Form\\Field\\StatusField', '5.0');
JLoader::registerAlias('JFormFieldTag', '\\Joomla\\CMS\\Form\\Field\\TagField', '5.0');
JLoader::registerAlias('JFormFieldTemplatestyle', '\\Joomla\\CMS\\Form\\Field\\TemplatestyleField', '5.0');
JLoader::registerAlias('JFormFieldUserActive', '\\Joomla\\CMS\\Form\\Field\\UseractiveField', '5.0');
JLoader::registerAlias('JFormFieldUserGroupList', '\\Joomla\\CMS\\Form\\Field\\UsergrouplistField', '5.0');
JLoader::registerAlias('JFormFieldUserState', '\\Joomla\\CMS\\Form\\Field\\UserstateField', '5.0');
JLoader::registerAlias('JFormFieldUser', '\\Joomla\\CMS\\Form\\Field\\UserField', '5.0');
JLoader::registerAlias('JFormRuleBoolean', '\\Joomla\\CMS\\Form\\Rule\\BooleanRule', '5.0');
JLoader::registerAlias('JFormRuleCalendar', '\\Joomla\\CMS\\Form\\Rule\\CalendarRule', '5.0');
JLoader::registerAlias('JFormRuleCaptcha', '\\Joomla\\CMS\\Form\\Rule\\CaptchaRule', '5.0');
JLoader::registerAlias('JFormRuleColor', '\\Joomla\\CMS\\Form\\Rule\\ColorRule', '5.0');
JLoader::registerAlias('JFormRuleEmail', '\\Joomla\\CMS\\Form\\Rule\\EmailRule', '5.0');
JLoader::registerAlias('JFormRuleEquals', '\\Joomla\\CMS\\Form\\Rule\\EqualsRule', '5.0');
JLoader::registerAlias('JFormRuleNotequals', '\\Joomla\\CMS\\Form\\Rule\\NotequalsRule', '5.0');
JLoader::registerAlias('JFormRuleNumber', '\\Joomla\\CMS\\Form\\Rule\\NumberRule', '5.0');
JLoader::registerAlias('JFormRuleOptions', '\\Joomla\\CMS\\Form\\Rule\\OptionsRule', '5.0');
JLoader::registerAlias('JFormRulePassword', '\\Joomla\\CMS\\Form\\Rule\\PasswordRule', '5.0');
JLoader::registerAlias('JFormRuleRules', '\\Joomla\\CMS\\Form\\Rule\\RulesRule', '5.0');
JLoader::registerAlias('JFormRuleTel', '\\Joomla\\CMS\\Form\\Rule\\TelRule', '5.0');
JLoader::registerAlias('JFormRuleUrl', '\\Joomla\\CMS\\Form\\Rule\\UrlRule', '5.0');
JLoader::registerAlias('JFormRuleUsername', '\\Joomla\\CMS\\Form\\Rule\\UsernameRule', '5.0');

JLoader::registerAlias('JMicrodata', '\\Joomla\\CMS\\Microdata\\Microdata', '5.0');

JLoader::registerAlias('JFactory', '\\Joomla\\CMS\\Factory', '5.0');

JLoader::registerAlias('JMail', '\\Joomla\\CMS\\Mail\\Mail', '5.0');
JLoader::registerAlias('JMailHelper', '\\Joomla\\CMS\\Mail\\MailHelper', '5.0');
JLoader::registerAlias('JMailWrapperHelper', '\\Joomla\\CMS\\Mail\\MailWrapper', '4.0');

JLoader::registerAlias('JClientHelper', '\\Joomla\\CMS\\Client\\ClientHelper', '5.0');
JLoader::registerAlias('JClientWrapperHelper', '\\Joomla\\CMS\\Client\\ClientWrapper', '5.0');
JLoader::registerAlias('JClientFtp', '\\Joomla\\CMS\\Client\\FtpClient', '5.0');
JLoader::registerAlias('JFTP', '\\Joomla\\CMS\\Client\\FtpClient', '4.0');
JLoader::registerAlias('JClientLdap', '\\Joomla\\Ldap\\LdapClient', '5.0');
JLoader::registerAlias('JLDAP', '\\Joomla\\Ldap\\LdapClient', '4.0');

JLoader::registerAlias('JUpdate', '\\Joomla\\CMS\\Updater\\Update', '5.0');
JLoader::registerAlias('JUpdateAdapter', '\\Joomla\\CMS\\Updater\\UpdateAdapter', '5.0');
JLoader::registerAlias('JUpdater', '\\Joomla\\CMS\\Updater\\Updater', '5.0');
JLoader::registerAlias('JUpdaterCollection', '\\Joomla\\CMS\\Updater\\Adapter\\CollectionAdapter', '5.0');
JLoader::registerAlias('JUpdaterExtension', '\\Joomla\\CMS\\Updater\\Adapter\\ExtensionAdapter', '5.0');

JLoader::registerAlias('JCrypt', '\\Joomla\\CMS\\Crypt\\Crypt', '5.0');
JLoader::registerAlias('JCryptCipher', '\\Joomla\\CMS\\Crypt\\CipherInterface', '5.0');
JLoader::registerAlias('JCryptKey', '\\Joomla\\CMS\\Crypt\\Key', '5.0');
JLoader::registerAlias('JCryptPassword', '\\Joomla\\CMS\\Crypt\\CryptPassword', '4.0');
JLoader::registerAlias('JCryptCipherBlowfish', '\\Joomla\\CMS\\Crypt\\Cipher\\BlowfishCipher', '4.0');
JLoader::registerAlias('JCryptCipherCrypto', '\\Joomla\\CMS\\Crypt\\Cipher\\CryptoCipher', '5.0');
JLoader::registerAlias('JCryptCipherMcrypt', '\\Joomla\\CMS\\Crypt\\Cipher\\McryptCipher', '4.0');
JLoader::registerAlias('JCryptCipherRijndael256', '\\Joomla\\CMS\\Crypt\\Cipher\\Rijndael256Cipher', '4.0');
JLoader::registerAlias('JCryptCipherSimple', '\\Joomla\\CMS\\Crypt\\Cipher\\SimpleCipher', '4.0');
JLoader::registerAlias('JCryptCipherSodium', '\\Joomla\\CMS\\Crypt\\Cipher\\SodiumCipher', '5.0');
JLoader::registerAlias('JCryptCipher3Des', '\\Joomla\\CMS\\Crypt\\Cipher\\TripleDesCipher', '4.0');
JLoader::registerAlias('JCryptPasswordSimple', '\\Joomla\\CMS\\Crypt\\Password\\SimpleCryptPassword', '4.0');

JLoader::registerAlias('JStringPunycode', '\\Joomla\\CMS\\String\\PunycodeHelper', '5.0');

JLoader::registerAlias('JBuffer', '\\Joomla\\CMS\\Utility\\BufferStreamHandler', '5.0');
JLoader::registerAlias('JUtility', '\\Joomla\\CMS\\Utility\\Utility', '5.0');

JLoader::registerAlias('JInputCli', '\\Joomla\\CMS\\Input\\Cli', '5.0');
JLoader::registerAlias('JInputCookie', '\\Joomla\\CMS\\Input\\Cookie', '5.0');
JLoader::registerAlias('JInputFiles', '\\Joomla\\CMS\\Input\\Files', '5.0');
JLoader::registerAlias('JInput', '\\Joomla\\CMS\\Input\\Input', '5.0');
JLoader::registerAlias('JInputJSON', '\\Joomla\\CMS\\Input\\Json', '5.0');

JLoader::registerAlias('JFeed', '\\Joomla\\CMS\\Feed\\Feed', '5.0');
JLoader::registerAlias('JFeedEntry', '\\Joomla\\CMS\\Feed\\FeedEntry', '5.0');
JLoader::registerAlias('JFeedFactory', '\\Joomla\\CMS\\Feed\\FeedFactory', '5.0');
JLoader::registerAlias('JFeedLink', '\\Joomla\\CMS\\Feed\\FeedLink', '5.0');
JLoader::registerAlias('JFeedParser', '\\Joomla\\CMS\\Feed\\FeedParser', '5.0');
JLoader::registerAlias('JFeedPerson', '\\Joomla\\CMS\\Feed\\FeedPerson', '5.0');
JLoader::registerAlias('JFeedParserAtom', '\\Joomla\\CMS\\Feed\\Parser\\AtomParser', '5.0');
JLoader::registerAlias('JFeedParserNamespace', '\\Joomla\\CMS\\Feed\\Parser\\NamespaceParserInterface', '5.0');
JLoader::registerAlias('JFeedParserRss', '\\Joomla\\CMS\\Feed\\Parser\\RssParser', '5.0');
JLoader::registerAlias('JFeedParserRssItunes', '\\Joomla\\CMS\\Feed\\Parser\\Rss\\ItunesRssParser', '5.0');
JLoader::registerAlias('JFeedParserRssMedia', '\\Joomla\\CMS\\Feed\\Parser\\Rss\\MediaRssParser', '5.0');

JLoader::registerAlias('JImage', '\\Joomla\\CMS\\Image\\Image', '5.0');
JLoader::registerAlias('JImageFilter', '\\Joomla\\CMS\\Image\\ImageFilter', '5.0');
JLoader::registerAlias('JImageFilterBackgroundfill', '\\Joomla\\Image\\Filter\\Backgroundfill', '5.0');
JLoader::registerAlias('JImageFilterBrightness', '\\Joomla\\Image\\Filter\\Brightness', '5.0');
JLoader::registerAlias('JImageFilterContrast', '\\Joomla\\Image\\Filter\\Contrast', '5.0');
JLoader::registerAlias('JImageFilterEdgedetect', '\\Joomla\\Image\\Filter\\Edgedetect', '5.0');
JLoader::registerAlias('JImageFilterEmboss', '\\Joomla\\Image\\Filter\\Emboss', '5.0');
JLoader::registerAlias('JImageFilterNegate', '\\Joomla\\Image\\Filter\\Negate', '5.0');
JLoader::registerAlias('JImageFilterSketchy', '\\Joomla\\Image\\Filter\\Sketchy', '5.0');
JLoader::registerAlias('JImageFilterSmooth', '\\Joomla\\Image\\Filter\\Smooth', '5.0');

JLoader::registerAlias('JObject', '\\Joomla\\CMS\\Object\\CMSObject', '5.0');

JLoader::registerAlias('JExtensionHelper', '\\Joomla\\CMS\\Extension\\ExtensionHelper', '5.0');

JLoader::registerAlias('JHtml', '\\Joomla\\CMS\\HTML\\HTMLHelper', '5.0');
星期三, 25 12月 2019 08:28

joomla中的userstate,或者说session处理

三个函数:

setUserState 和 getUserState是一对,一个设置一个读取;
 
还有一个是getUserStateFromRequest,边读取边设置。因为很多情景下,userstate是从form传进来的,所以,可以读取的时候,顺便用request中的值把state更新了。
 
userstate的值存在哪?当然是存在session里了。后台打开调试模式,会发现,userstate的值都存在session下的registry数组中。并列的数组还有,user,default,等。
 
但如果直接打印_SESSION,发现没有数组。joomla给加密了。挺好!

Why should I use the Joomla! User State Variables?

Joomla!'s built in session handling capabilities make it easy to retain values of certain variables across page accesses. This makes development much simpler because the developer no longer has to worry about losing variable values if it is left out of a form. Storing variables with sessions also makes the application cleaner and tidier since it reduces the amount of form variables, and persistent variables no longer have to be passed in either the query string (making very long URLs) or in POST variables.

The downside of using session variables is that it makes page URLs stateful. That is, if used improperly, a URL might point to certain information in one context, but different information in another context. This can make search engines less effective since the web crawler might pull up a certain page using a certain URL, that when the user links to the URL from the search engine, might pull up a different page, resulting in user confusion and frustration.

Setting and retrieving user state variables

There are two ways to set user state variables. The first is fairly intuitive, and is done using the JApplication::setUserState method. The second is a little less obvious, and uses the JApplication::getUserStateFromRequest method. There are also two ways to retrieve user state variables. The first is using the JApplication::getUserState method, and the second is to use the JApplication::getUserStateFromRequest method. JApplication::getUserStateFromRequest can be used to both store and retrieve user state variables.

The following methods are used for accessing the user state variables:

Method 1: JApplication::setUserState

$mainframe =JFactory::getApplication();

// store the variable that we would like to keep for next time
// function syntax is setUserState( $key, $value );
$mainframe->setUserState( "$option.state_variable", "state1" );

The first parameter is the key under which to store the variable. You will note that in this example the key began with the $option variable. Although the value for $key is arbitrary, it is good practice to use this as a prefix for all user state variables since these are all in the same name space. Using an extension-specific prefix avoids extensions interfering with each other. In the example above, state_variable is the name of the state variable that will be stored, and the second parameter is the value to store with the state variable.

Method 2: JApplication::getUserStateFromRequest

$mainframe =JFactory::getApplication();

// retrieve the value of the state variable. First see if the variable has been passed
// in the request. Otherwise retrieve the stored value. If none of these are specified,
// the specified default value will be returned
// function syntax is getUserStateFromRequest( $key, $request, $default );
$stateVar = $mainframe->getUserStateFromRequest( "$option.state_variable", 'state_variable', 'state1' );

The first parameter is the key under which to store the variable. Note again that this is prefixed with the name of the current extension. This method will update the user state variable by looking in the variables that were passed with the request (in either GET or POST) and updating the user state variable if the specified request variable is set. This can be used to set user state variables with values that are passed from forms (i.e. from the user). If an existing value can be found either in the request or in the stored state variable, this is returned. Otherwise, the specified default value is returned (if it is specified), or NULL is returned if no value can be found.

Method 3: JApplication::getUserState

$mainframe =JFactory::getApplication();

// retrieve the value of the state variable. If no value is specified,
// the specified default value will be returned.
// function syntax is getUserState( $key, $default );
$stateVar = $mainframe->getUserState( "$option.state_variable", 'state1' );

The first parameter is the key under which to store the variable. Note again that this is prefixed with the name of the current extension. This method will retrieve the value of the specified user state variable. If this user state variable has not been set, then the value is read from the $default parameter. If the user state variable has not been set and $default is not specified, the method will return NULL.

A real life example of the use of Joomla! user state variables

The following code excerpts are taken from the admin section of the Newsfeed component, which is a core Joomla! component. These snippets are meant to demonstrate how user state variable can be used in an actual application.

Purpose

Notice that many components that have database tables associated with them present to the user a list of items. In the case of the Newsfeed component, the administration section presents a list of Newsfeeds. If there are too many newsfeeds to list on one page, two variables are used to keep track of where the user is in the list: the limit variable and the limitstart variable. The Newsfeed component (like other components) uses state variables to store the value of limit and limitstart between page requests.

If a user goes to administer another component or navigates away from the component, these values are available when the user returns. In addition, these values only have to be passed if they are being changed. The developer does not have to bother with inserting hidden form feeds to pass these values along.

Setting and retrieving the variables

The following code is used to set and retrieve the values of these variables:

$mainframe =JFactory::getApplication();

$limit = $mainframe->getUserStateFromRequest( "limit", 'limit', $mainframe->getCfg('list_limit') );
$limitstart = $mainframe->getUserStateFromRequest( "$option.limitstart", 'limitstart', 0 );

The first variable that is stored is the limit variable. The limit variable specifies how many records should be retrieved from the database and displayed. Note that there is no $option prefix in the $key parameter. This variable is used as a global parameter (and its initial value is retrieved from the site configuration value). The value is retrieved from the request variable called 'limit'. If the state variable has not been specified yet and it is not specified in the request, then the value is retrieved from the site configuration using the JApplication::getCfg method.

The second variable that is stored is the limitstart variable. This specifies how many records to skip over before returning records from the database. Each component has its own list and so keeps its own place in its own list. The $option parameter in this case has the value 'com_newsfeeds', and so the session variable name is 'com_newsfeeds.limitstart'.

Passing values to JPagination class

In this example, the stored values are used as parameters for constructing the pagination class, which helps the developer implement pagination functionality.

Ultimately, this will result in the following form elements being displayed on the page:

<div class="limit">Display #
<select name="limit" id="limit" class="inputbox" size="1" onchange="document.adminForm.submit();">
<option value="5"  selected="selected">5</option>
<option value="10" >10</option>
<option value="15" >15</option>
<option value="20" >20</option>
<option value="25" >25</option>
<option value="30" >30</option>
<option value="50" >50</option>
<option value="100" >100</option></select>
</div>

<div class="start"><span>Start</span></div>
<div class="button2-right off"><div class="prev"><span>Prev</span></div></div>
<div class="button2-left"><div class="page">
<span>1</span>
<a title="2" onclick="javascript: document.adminForm.limitstart.value=5; document.adminForm.submit();return false;">2</a>
</div></div>

<div class="button2-left"><div class="next">
<a title="Next" onclick="javascript: document.adminForm.limitstart.value=5; document.adminForm.submit();return false;">Next</a>
</div></div>

<div class="button2-left"><div class="end"><a title="End" onclick="javascript: document.adminForm.limitstart.value=5; document.adminForm.submit();return false;">End</a></div></div>

<div class="limit">
Results 1 - 5 of 10</div>

<input type="hidden" name="limitstart" value="0" />

One may be observant and notice that the values are passed in hidden form elements anyway, and claim therefore that it is really not necessary to use state variables. But this will not help in the situation where the user has navigated away from the component, and it will also not help in the situation which occurs in the list, for example, where each newsfeed is listed and linked using a standard link, and not the form. Using state variables saves having to add limit and limitstart on to the end of these URLs.

第 1 页 共 2 页

博客标签

© Copyright 2020 zhuameng.com. All Rights Reserved.鲁ICP备16037764号-3

Search