The release of the new version of the module modLivestreet 0.3.0-rc
Continuing our theme of the binding module MODX and Livestreet, present a new version of the module modLivestreet: livestreet-0.3.0-rc.transport.zip
What's new? Yes, almost all :-) the Module is rewritten from scratch.
1. Seriously changed (improved) the logic of processing requests LiveStreet.
2. Added synchronized registration of users in MODX and LiveStreet. Now registering user through the admin panel of MODX, the user is automatically created in LiveStreet, and processing the request for LiveStreet on the user registration, the registration is using MODX, which in turn also provides for the simultaneous registration of the user in both engines.
This feature can be disabled through configuration.
Under the cut diagram (simplified) MODX in the standard version and module modLivestreet and a more detailed description of the synchronous registration of users in MODX and Livestreet (Scheme, how has the registration in the MODX upload later), as well as the source code.
UPD: building the package on github: github.com/Fi1osof/modx-livestreet
So how does this module?
1. The most important plugin in this module is triggered on two events — onHandleRequest and onPageNotFound.
In the first case, the test requests to Livestreet in principle (and initialization of the variables Livestreet) and check for referring to static files Livestreet and its individual modules (like Captcha).
The latter is another problem: if the processing request found MODX landing page, the event onPageNotFound in principle won't work, and LiveStreet will not be processed if the document is not explicitly invoked MODX snippet livestreet.run, which executes a query on LiveStreet. This approach allows us not to tie MODX just for LiveStreet. That is, we can do on MODX completely independent website, but to make the section /forum/ (or a separate subdomain forum.site.ru) to determine that there is an incoming page, to register it in the snippet call [[!livestreet.ru]] (to site root) in the settings to specify livestreet.url_perfix '/forum/' and all. All requests for a mask /forum/.* will be executed with a call to LiveStreet and we get your blog. Here you can write a check right or call only certain branches of the blog, etc.
In case, if the document is not found and the onPageNotFound event is invoked, and the URL corresponds to a section Livestreet, there is already a request for Livestreet. There is a small caveat: if it's a request for user registration Livestreet, then the call to the snippet register a user snippet.livestreet.ajax-registration.php
Basically, as you can see, the plugin is not great for such functionality. So anyone will understand if he wants to modify it to fit your needs.
2. Requests for use LiveStreet snippet snippet.livestreet.run
It is quite small. Stupidly called LiveStreet, display operations and return the result. Therefore, you and content processing before output, and the results of Ajax requests to be processed for verification (this is especially important when performing the user registration, as in the case of synchronous registration of users in MODX and LiveSteet you need to cancel the registration if verification of user registration both in MODX and Livestreet).
Then again, a reservation. In Livestreet does not properly class content output works. In output mode, Ajax-results LS makes a stupid exit (); that breaks off the whole module. Because in LS you must do a little manipulation:
In the file components/livestreet/docs/forLiveStreet/source/engine/modules/viewer/Viewer.class.php
in the method DisplayAjax($sType='json'), replace exit(); return;
in the method Display($sTemplate) replace the
Essentially it will not change independent work Livesreet, but will give us the opportunity to process the results of Ajax queries and to continue your logic.
3. Snippet livestreet.ajax registration.
This snippet processes a request to register the user Livestreet.
If the option is disabled synchronous registration, the snippet is not executed, and if it is a direct request for user registration in Livestreet, Livestreet request is sent to all.
If simultaneous check is enabled, the request is sent not on Livestreet, and for registration of user in MODX (called processor core/components/livestreet/processors/security/user/ajaxCreate.class.php where is called the extended class modUserCreateProcessor). The essence of the challenge of this processor is simple — to call the base processor to create a MODX user via the system processor modx/processors/security/user/create.class.php
The reason for this challenge is that we cannot directly invoke this processor, since it checks for the right to create new users, and that right there is from unauthorized user. Because in this class we just fill the check this law (For the tip this reception special thanks to bezumkin).
Well, when there is registration of the user in MODX, we hang our plugin livestreet_users the event OnBeforeUserFormSave.
What's new? Yes, almost all :-) the Module is rewritten from scratch.
1. Seriously changed (improved) the logic of processing requests LiveStreet.
2. Added synchronized registration of users in MODX and LiveStreet. Now registering user through the admin panel of MODX, the user is automatically created in LiveStreet, and processing the request for LiveStreet on the user registration, the registration is using MODX, which in turn also provides for the simultaneous registration of the user in both engines.
This feature can be disabled through configuration.
Under the cut diagram (simplified) MODX in the standard version and module modLivestreet and a more detailed description of the synchronous registration of users in MODX and Livestreet (Scheme, how has the registration in the MODX upload later), as well as the source code.
UPD: building the package on github: github.com/Fi1osof/modx-livestreet
Promised schemes of work MODX in the standard Assembly and module modLivestreet
So how does this module?
1. The most important plugin in this module is triggered on two events — onHandleRequest and onPageNotFound.
In the first case, the test requests to Livestreet in principle (and initialization of the variables Livestreet) and check for referring to static files Livestreet and its individual modules (like Captcha).
The latter is another problem: if the processing request found MODX landing page, the event onPageNotFound in principle won't work, and LiveStreet will not be processed if the document is not explicitly invoked MODX snippet livestreet.run, which executes a query on LiveStreet. This approach allows us not to tie MODX just for LiveStreet. That is, we can do on MODX completely independent website, but to make the section /forum/ (or a separate subdomain forum.site.ru) to determine that there is an incoming page, to register it in the snippet call [[!livestreet.ru]] (to site root) in the settings to specify livestreet.url_perfix '/forum/' and all. All requests for a mask /forum/.* will be executed with a call to LiveStreet and we get your blog. Here you can write a check right or call only certain branches of the blog, etc.
In case, if the document is not found and the onPageNotFound event is invoked, and the URL corresponds to a section Livestreet, there is already a request for Livestreet. There is a small caveat: if it's a request for user registration Livestreet, then the call to the snippet register a user snippet.livestreet.ajax-registration.php
listing plug-in
<?php
switch($modx->context->key){
case 'web':
break;
default: return;
}
switch($modx->event->name){
// Here we will check the possible requests for static content LiveStreet
case 'OnHandleRequest':
// To load the file config livestreet_path/config/
define('IN_MODX', true);
define('LIVESTREET_WEB', $modx- > getOption('site_url'));
define('LIVESTREET_PATH', $modx- > getOption('livestreet.livestreet_path'));
define('LIVESTREET_INDEX_FILE', $modx- > getOption('livestreet.index_file'));
define('LIVESTREET_URL_PREFIXE', $modx- > getOption('livestreet.url_prefix'));
$request = false;
//print "<br />REQUEST_URI:" . $_SERVER['REQUEST_URI'];
// Define whether a request for LiveStreet
if($_SERVER['REQUEST_URI'] == LIVESTREET_URL_PREFIXE || $_SERVER['REQUEST_URI']."/" == LIVESTREET_URL_PREFIXE){
$request = '/';
}
else{
// If it is not part LiveStreet, noise
$preg = str_replace('/', '\/', LIVESTREET_URL_PREFIXE);
if(!preg_match("/^{$preg}/", $_SERVER['REQUEST_URI']."/")){
return;
}
$request = preg_replace("/^{$preg}/", ", $_SERVER['REQUEST_URI']);
}
if( substr( $request, 0, 1) != '/') $request = '/'. $request;
// Fix the query on the LS
define('LIVESTREET_REQUEST_URI', $request);
// Check the status of the site so as not to give the content if the site closed
if(!$modx->checkSiteStatus()){
return;
}
$file = LIVESTREET_INDEX_FILE;
/*$t = $modx- > invokeEvent('onLivestreetUserSave', array('sdfsdf'));
exit;*/
// Check for access directory LiveStreet
$preg = str_replace('/', '\/', "(/templates/|/uploads/|/engine/lib/external/jquery)");
if(preg_match("/^{$preg}/", LIVESTREET_REQUEST_URI)){
$file = LIVESTREET_REQUEST_URI;
$file = preg_replace('/\?+.*/', ", $file);
$fullpath = str_replace('//','/', LIVESTREET_PATH.$file);
if(!file_exists($fullpath)){
die('File Not Found');
}
$fsize = filesize($fullpath);
$pi = pathinfo( $file);
$ext = $pi['extension'];
switch ($ext) {
case "css": $ctype="text/css; charset=utf-8"; break;
case "js": $ctype="application/x-javascript; charset=utf-8"; break;
case "pdf": $ctype="application/pdf"; break;
case "exe": $ctype="application/octet-stream"; break;
case "zip": $ctype="application/zip"; break;
case "doc": $ctype="application/msword"; break;
case "xls": $ctype="application/vnd.ms-excel"; break;
case "ppt": $ctype="application/vnd.ms-powerpoint"; break;
case "gif": $ctype="image/gif"; break;
case "png": $ctype="image/png"; break;
case "jpeg":
case "jpg": $ctype="image/jpg"; break;
default: $ctype="application/force-download";
}
header("Content-type: {$ctype}", true);
header("Content-Length: ".$fsize);
header("last-modified: ". gmdate("d, d m y h:i:s", filemtime($fullpath) )." GMT");
header("Pragma: public");
header("Expires: 0");
readfile($fullpath);
exit;
}
/*
* Determined whether any module to run
*/
// Captcha
$preg = str_replace('/', '\/', "/engine/lib/external/kcaptcha/");
if(preg_match("/^{$preg}/", LIVESTREET_REQUEST_URI)){
$file = 'engine/lib/external/kcaptcha/index.php';
require_once LIVESTREET_PATH.$file;
exit;
}
break;
case 'OnPageNotFound':
// if not LiveStreet the request, stop
if(!defined('LIVESTREET_REQUEST_URI')){
return;
}
$_SERVER['REQUEST_URI'] = LIVESTREET_REQUEST_URI;
// Registration
if(LIVESTREET_REQUEST_URI == $modx- > getOption('livestreet.registration_url', null, '/registration/ajax-registration/')){
// if not in sync mode
if($modx- > getOption('livestreet.sync_users') == true){
print $modx- > runSnippet('livestreet.ajax-registration');
exit;
}
}
print $modx- > runSnippet('livestreet.run');
exit;
break;
default:
$modx->event->output( 'true');
;
}
Basically, as you can see, the plugin is not great for such functionality. So anyone will understand if he wants to modify it to fit your needs.
2. Requests for use LiveStreet snippet snippet.livestreet.run
Listing
<?php
if($request_uri){
$_SERVER['REQUEST_URI'] = $request_uri;
}
ob_start();
@include $modx- > getOption('livestreet.livestreet_path').$modx- > getOption('livestreet.index_file');
$output = ob_get_contents();
ob_end_clean();
return $output;
It is quite small. Stupidly called LiveStreet, display operations and return the result. Therefore, you and content processing before output, and the results of Ajax requests to be processed for verification (this is especially important when performing the user registration, as in the case of synchronous registration of users in MODX and LiveSteet you need to cancel the registration if verification of user registration both in MODX and Livestreet).
Then again, a reservation. In Livestreet does not properly class content output works. In output mode, Ajax-results LS makes a stupid exit (); that breaks off the whole module. Because in LS you must do a little manipulation:
In the file components/livestreet/docs/forLiveStreet/source/engine/modules/viewer/Viewer.class.php
in the method DisplayAjax($sType='json'), replace exit(); return;
in the method Display($sTemplate) replace the
if ($this->sResponseAjax) {
$this->DisplayAjax($this->sResponseAjax);
}
if ($this->sResponseAjax) {
$this->DisplayAjax($this->sResponseAjax);
return;
}
Essentially it will not change independent work Livesreet, but will give us the opportunity to process the results of Ajax queries and to continue your logic.
3. Snippet livestreet.ajax registration.
This snippet processes a request to register the user Livestreet.
Listing
<?php
// if not in sync mode
if($modx- > getOption('livestreet.sync_users') != true){
return;
}
$path = $modx- > getObject('modNamespace', array(
'name' => 'livestreet'
)) -> getCorePath()."processors/";
// print $path;
// exit;
$response = $modx- > runProcessor('security/user/ajaxCreate', array(
'username' => $_POST['login'],
'email' => $_POST['mail'],
'passwordnotifymethod' => 'false'
'passwordgenmethod' => 'false'
'specifiedpassword' => $_POST['password'],
'confirmpassword' => $_POST['password_confirm'],
), array(
'processors_path' => $path
));
$bStateError = false;
$sMsgTitle = null;
$sMsg = null;
$errors = array();
if($response->isError()){
// print '<pre>';
//print_r($modx->error->errors);
$errorsArray = (array)$modx->error->errors;
// processEventResponse
// $error = $response->getMessage();
if($errMessageArr = (array)explode("\n", $response->getMessage())){
if(!$message = trim($message))continue;
if(!$errArr = explode('::', $message) OR count($errArr) != 2){
$sMsg = $message;
}
else{
$errorsArray[] = array(
'id' => $errArr[0],
'msg' => $errArr[1],
);
}
}
}
foreach($errorsArray as $err){
// LiveStreet Errors
if($name = $err['id']){
switch($name){
case 'username':
$name = 'login';
break;
case 'specifiedpassword':
$name = 'password';
break;
case 'confirmpassword':
$name = 'password_confirm';
break;
default: continue;
}
$errors[$name][0] = $err['msg'];
}
// MODX errors
else{
$sMsg = current($err);
}
}
if(!$errors && !$sMsg){
$sMsg = 'Error executing query';
}
if($sMsg){
$sMsgTitle = 'Error';
$bStateError = true;
}
$response = array(
'sMsgTitle' => $sMsgTitle,
'sMsg' = > $sMsg,
'bStateError' => $bStateError,
'aErrors' = > $errors
);
}
else{
// Success
$response = array(
'sMsgTitle' => null,
'sMsg' => 'Congratulations! Registration was successful!',
'bStateError' => false,
'sUrlRedirect' => $_POST['return-path'],
);
}
return json_encode($response);
If the option is disabled synchronous registration, the snippet is not executed, and if it is a direct request for user registration in Livestreet, Livestreet request is sent to all.
If simultaneous check is enabled, the request is sent not on Livestreet, and for registration of user in MODX (called processor core/components/livestreet/processors/security/user/ajaxCreate.class.php where is called the extended class modUserCreateProcessor). The essence of the challenge of this processor is simple — to call the base processor to create a MODX user via the system processor modx/processors/security/user/create.class.php
The reason for this challenge is that we cannot directly invoke this processor, since it checks for the right to create new users, and that right there is from unauthorized user. Because in this class we just fill the check this law (For the tip this reception special thanks to bezumkin).
Listing
<?php
$file = MODX_PROCESSORS_PATH.'security/user/create.class.php';
if(!file_exists($file)){
class modLivestreetUserCreateErrorProcessor extends modProcessor {
public function process() {
$err = 'processor security/user/create 'not found';
$this- > modx- > log(modX::LOG_LEVEL_ERROR, $err);
return $this- > failure($err);
}
}
return 'modLivestreetUserCreateErrorProcessor';
}
require_once $file;
class modLivestreetUserCreateProcessor extends modUserCreateProcessor {
public $permission = ";
}
return 'modLivestreetUserCreateProcessor';
Well, when there is registration of the user in MODX, we hang our plugin livestreet_users the event OnBeforeUserFormSave.
Listing
Article based on information from habrahabr.ru
<?php
/*
* Synchronized registration of MODX and Livestreet users
*/
switch($modx->event->name){
case 'OnBeforeUserFormSave':
switch($scriptProperties['mode']){
// Register new user
case 'new':
// if not in sync mode
if($modx- > getOption('livestreet.sync_users') != true){
return;
}
// Using for LiveStreet ModuleSecurity::GenerateSessionKey
// check password method
if($scriptProperties['data']['passwordgenmethod'] == 'g'){
$len = $modx- > getOption('password_generated_length',null,8);
$password = $password_confirm = modUserValidation::generatePassword($len);
/*
* note newPassword then in createProcessor will not be overwrited !!!
* in the backend will see wron new passrowd
*/
$scriptProperties['user']->set('password', $password);
}
else{
$password = $scriptProperties['data']['specifiedpassword'];
$password_confirm = $scriptProperties['data']['confirmpassword'];
}
$_REQUEST['password'] = $password;
$_REQUEST['password_confirm'] = $password_confirm;
$_REQUEST['login'] = $scriptProperties['data']['username'];
$_REQUEST['mail'] = $scriptProperties['data']['email'];
$_REQUEST['login'] = $scriptProperties['data']['username'];
if($modx->context->key == 'mgr'){
$captcha = time();
$_SESSION['captcha_keystring'] = $captcha;
$_REQUEST['captcha'] = $captcha;
$_SESSION['user_id'] = ";
$_REQUEST['security_ls_key'] = md5( session_id(). $modx- > getOption('livestreet.module.security.hash', null, 'livestreet_security_key'));
}
$response = $modx- > runSnippet('livestreet.run', array(
'request_uri' => $modx- > getOption('livestreet.registration_url')
));
$response = json_decode($response);
if(!is_object($response)){
$modx->event->output('Error running query');
}
elseif($response- > aErrors){
$errors = ";
$errors__ = array();
foreach((array)$response- > aErrors as $f => $val){
$errors .= "$f:: ". $val[0]."\n";
}
$modx->event->_output = $errors;
}
return;
break;
default:;
}
break;
default:$modx- > log(modX::LOG_LEVEL_ERROR, "Wrong Event: ". $modx->event->name);
At the time of user registration of MODX, after all checks (if all OK), run the plugin and there is an attempt of user registration in LiveStreet. If the attempt breaks off, return error LiveStreet and interrupt the user registration of MODX. If everything is OK, finally logged in user in MODX.
Thus we achieve that the user can Regit and through the admin panel MODX, and through the FrontEnd, and there we will see all possible errors, and get the registration of the user in MODX and LiveStreet. And in the future these users if necessary can link by email (as in LS email — unique key).
That's all :-)
Here's what I like about MODX:-) We have seriously changed the engine, not touching and byte code of the engine.
But under no MODX module the social sphere.
But Livestreet — good social programs, but it does not give such API, as MODX. They even admin as such, no.
But together, these engines can give a great product! I will continue to develop this module.
UPD 2:new release: modlivestreet-0.4.1-rc.transport.zip
New:
1. All items and settings are now prefixed modLivestreet, because unfortunately the new module is not backwards compatible with the previous version. But certainly it's not going to be a problem. Enough to remove the old module and put the new one in the main page to change
2. Added check for extension of the downloaded files in the directory /templates/, /uploads/, etc. to not pumping .php, etc.
Of course such files are there and should not be, but at least /skin/config/ this file exists.
UPD 3: a Note on security: modxlivestreet.ru/blog/modLivestreet_security/7.html
Комментарии
Отправить комментарий