As I fought with contexts

As a true conservative, I long time used exclusively MODx Evolution. I was first of all the availability of comprehensive documentation, heaps of articles and extremely clear architecture this version of MODx CMF. About the version of Revolution I periodically read various articles, but I didn't want to change my system for anything else. However, at one point, the number of tables in the database for my multi-domain "hamster" on the host has reached staggering proportions. There was a question about multi-domain solution. Once I read about the possibility to create in MODx Revolution multi-domain website. I installed the engine on a test subdomain and started to dig deeper. As it turned out, in the framework, such as ready solutions about multidomainhost not yet exist. There is a certain system contexts. Different contexts can be defined in different subdomains. But for this you need to edit the file index.php.

The first thing that comes to mind is to use already proven popular code:

the
switch($_SERVER['SERVER_NAME']) {
case 'sub1.domain.tld': $modx- > initialize('sub1'); break;
case 'sub2.domain.tld': $modx- > initialize('sub2'); break;
case 'sub3.domain.tld': $modx- > initialize('sub3'); break;
default: $modx- > initialize('web');
}


If, say, You have on the system contexts based multilingual, then you can do even this:

the
switch($_SERVER['SERVER_NAME']) {
case 'domain.ru': case 'www.domain.ru': $modx- > initialize('EN'); break; // switch to Russian
case 'domain.fr': case 'www.domain.fr': $modx- > initialize('fr'); break; // switch to French (for example)
default: $modx- > initialize('web');
}


And not much of the big portals, where the number of subdomains is controlled by the administrator of the hosting/domain and seldom changes, such decision will suffice for the eyes. However, let us fantasize. Do You have your own server. It can be Your personal server or VDS-ka for favorite hosting. You have the ability to programmatically create subdomains. Suppose that You write your analogue livejournal.com...

Create a context by calling the API is not very difficult. To go into details, I will not, not too much until I've studied the API MODx Revolution. However, to create the context and subdomain is one thing, but to tie it together is another. Here the above solution will not work, because you cannot know in advance how many sub-domains and will be referred to as contexts for them. The idea is that if the alias contexts match the names of the subdomains, then make a decision:

the
define("myRootDomain","domain.tld");
$ctxKey = 'web';

if (preg_match('#(\w+).'.myRootDomain.'#si',$_SERVER['SERVER_NAME']) > 0) {
$ctxKey = preg_replace('#(\w+).'.myRootDomain.'#si','\1',$_SERVER['SERVER_NAME']);
if ($ctxKey == 'www') $ctxKey = 'web';
}


Basic information about the contexts in MODx stored in the database tables context, context_setting. The first table holds the descriptions of the contexts (key, description, display order). The second context settings. Remember, in common outcomes, we need to specify error pages, host and the like? That is all there is stored. And the first thing that comes to mind is the SQL query for this table:

the
$SQL = "SELECT * FROM ".$table_prefix." WHERE `key`='http_host' AND `value`='".$_SERVER['SERVER_NAME']."'";


If the system contexts were provided in the old Evolution, then the algorithm would just be:

the
$ctxKey = 'web';
if ($result = $modx->db->query($SQL)) if ($row = mysql_fetch_assoc($result)) $ctxKey = $row['context_key'];


However, in this respect, MODx developers put developers who use MODx, a small pig, because the architecture of MODx Revolution is based on xPDO. And this is not familiar to us API, and a very different conversation.

After studying a bunch of results in Google search, including the official documentation on MODx Revolution API, I was not able to understand how easy to make a query to DB in MODx Revolution. But, having dug the file core/model/modx/modx.php I found something

the
$pluginEventTbl= $this->getTableName('modPluginEvent');
$eventTbl= $this->getTableName('modEvent');
$pluginTbl= $this->getTableName('modPlugin');
$propsetTbl= $this->getTableName('modPropertySet');
$sql= "
SELECT
Event.name AS event,
PluginEvent.pluginid,

FROM {$pluginEventTbl} PluginEvent
INNER JOIN {$pluginTbl} Plugin ON Plugin.id = PluginEvent.pluginid AND Plugin.disabled = 0
INNER JOIN {$eventTbl} Event ON {$service} Event.name = PluginEvent.event
LEFT JOIN {$propsetTbl} PropertySet ON PluginEvent.propertyset = PropertySet.id
ORDER BY Event.name, PluginEvent.priority ASC
";
$stmt= $this->prepare($sql);
if ($stmt &&$stmt->execute()) {
while ($ee = $stmt->fetch(PDO::FETCH_ASSOC)) {
$eventElementMap[$ee['event']][(string) $ee['pluginid']]= $ee['pluginid'] . (!empty($ee['propertyset']) ? ':' . $ee['propertyset'] : ");
}
}



This is a fragment of the method getEventMap class modX. It is logical to assume that instead of a long query we can insert your request and it is supposed to work as it should. The result is a solution:

the
$ctxCur = 'web';
$ctxQur = "SELECT * FROM `".$table_prefix."context_setting` WHERE `key`='http_host' AND `value`='".$_SERVER['SERVER_NAME']."'";
$ctxSQL = $modx->prepare($ctxQur);
if ($ctxSQL && $ctxSQL->execute()) if ($ctxRes = $ctxSQL->fetch(PDO::FETCH_ASSOC)) $ctxCur = $ctxRes['context_key'];

$modx- > initialize($ctxCur);


When using this solution, we need to worry only about the correct http_host field in the admin area. And the name of the context in this case does not necessarily coincide with the subdomain. And all SIM. Thank you for your attention to my next bike!
Article based on information from habrahabr.ru

Комментарии

Популярные сообщения из этого блога

Automatically create Liquibase migrations for PostgreSQL

Vkontakte sync with address book for iPhone. How it was done

What part of the archived web