As a true conservative, for a long time I used exclusively MODx Evolution. First of all, I was satisfied with the availability of comprehensive documentation, heaps of articles and an extremely clear architecture of this version of MODx CMF. I occasionally read various articles about the Revolution version, but I didn’t want to change my usual system to anything else. However, at one point, the number of tables in the database of my multi-domain "hamster" on the hosting has reached frightening sizes. There was a question about a multi-domain solution. I once read about the possibility of creating a multi-domain site on the MODx Revolution. I installed the engine on a test subdomain and started digging deeper. As it turned out, in the framework as such, there is no ready-made solution for multi-domain. There is a certain system of contexts. Different contexts can be defined for different subdomains. Only for this you need to edit the file index.php.
The first thing that comes to mind is to use the already proven popular code:
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 multilingualism on the context system, then you can even do this:
')
switch($_SERVER['SERVER_NAME']) { case 'domain.ru': case 'www.domain.ru': $modx->initialize('ru'); break;
And for not very large portals, where the number of subdomains is controlled by the hosting / domain administrator and rarely changes, this solution is enough for the eyes. However, let's fantasize with you. You have your own server. This can be your personal server or VDS on your favorite hosting. You have the ability to programmatically create subdomains. Suppose you are writing your analogue of livejournal.com ...
Creating a context using the API is not very difficult. I will not go into details, I have not studied the MODx Revolution API too much. Nevertheless, creating a context and a subdomain is one thing, but tying it together is another. Here, the above solutions will not work, for it is not known in advance how many subdomains will be available and how the contexts for them will be called. In theory, if the aliases of contexts coincide with the names of subdomains, then the solution is quite appropriate:
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 contexts in MODx is stored in the database in
context ,
context_setting tables . The first table contains descriptions of contexts (key, description, display order). In the second - context settings. Remember, in common solutions, we needed to register error pages, a host, and the like? This is all stored there. And the first thing that comes to mind is the SQL query to this table:
$SQL = "SELECT * FROM ".$table_prefix." WHERE `key`='http_host' AND `value`='".$_SERVER['SERVER_NAME']."'";
If the context system were provided in the old woman Evolution, then everything would be simple with the algorithm:
$ctxKey = 'web'; if ($result = $modx->db->query($SQL)) if ($row = mysql_fetch_assoc($result)) $ctxKey = $row['context_key'];
However, in this respect, the MODx developers have planted a small pig for developers using MODx, for the MODx Revolution architecture is based on xPDO. And this is not the usual API, but a completely different conversation.
Having studied a bunch of Google search results, including the official documentation on the MODx Revolution API, I still could not understand how easier it is to make a query to the database in MODx Revolution. But, having digged the
core / model / modx / modx.php file , I discovered something like the following:
$pluginEventTbl= $this->getTableName('modPluginEvent'); $eventTbl= $this->getTableName('modEvent'); $pluginTbl= $this->getTableName('modPlugin'); $propsetTbl= $this->getTableName('modPropertySet'); $sql= " SELECT Event.name AS event, PluginEvent.pluginid, PropertySet.name AS propertyset 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 getEventMap method of the modX class. It is logical to assume that instead of a long query, we can insert our own query and it is supposed to work out how it should be. As a result, a solution is born:
$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 care only about the correct indication of the http_host field in the admin panel. And the name of the context in this case does not have to match the subdomain. On this all. Thank you for your attention to my next bike!