PHP-консоль под MODx Revolution
P.S. Не надо лишних комментариев на счет безопасности. Если не знаете MODx Revolution, лучше вообще ничего не говорить. Так же перед постингом по безопасности читаем тут.

Система управления содержимым с открытым кодом
В CMF MODX Revolution изначально не предусмотрена возможность ставить задачи и привязывать их к ресурсам. Такое дополнение я тоже не нашел, да и было интересно разобраться в создании виджетов, поэтому придумал решение, как можно быстро реализовать такой функционал на своем сайте. Собственно, в этой статье хочу им поделиться.
Свежая подборка новостей о MODX. В выпуске: закрылся сайт modx-клуба, прогресс с конвертацией процессоров, активная работа над документацией, заметки и обновления дополнений.
Приятного чтения!
<?php
/*
Абстрактный класс на проведение оплаты.
Его нельзя вызывать напрямую, чтобы исключить случаи инжекта оплаты.
Этот класс должен расширяться другим классом конкретной платежной системы,
чтобы использовать методы проверки платежа самой платежной системы
*/
abstract class modWebPaymentsCreateProcessor extends modObjectCreateProcessor{
public $classKey = 'Payment';
protected $BillingProcessorsPath;
public function checkPermissions() {
// Проверяем подпись платежной системы
$ok = $this->checkSignature();
if($ok !== true){
$this->error($ok);
return false;
}
return parent::checkPermissions();
}
public function initialize(){
$this->BillingProcessorsPath = MODX_CORE_PATH . 'components/billing/processors/';
$this->setDefaultProperties(array(
'currency_id' => $this->modx->getOption('shopmodx.default_currency'),
));
if(!$this->getProperty('paysystem_id')){
return $this->error("Не был получен ID платежной системы");
}
return parent::initialize();
}
public function beforeSet(){
$this->setProperties(array(
"createdby" => $this->modx->user->id ? $this->modx->user->id : null,
"date" => time(),
));
return parent::beforeSet();
}
public function beforeSave(){
if(
!$currency_id = (int)$this->getProperty('currency_id')
OR !$currency = $this->modx->getObject('modResource', $currency_id)
OR ! $currency instanceof ShopmodxResourceCurrency
){
return $this->error("Не был получен объект валюты");
}
if(
!$paysystem_id = (int)$this->getProperty('paysystem_id')
OR !$paysystem = $this->modx->getObject('Paysystem', $paysystem_id)
OR ! $paysystem instanceof Paysystem
){
return $this->error("Не был получен объект платежной системы");
}
// Проверяем, если указан счет платежной системы, то надо убедиться, что
// он еще не числится в биллинге
if($paysys_invoice_id = $this->object->get('paysys_invoice_id')){
if($this->modx->getCount($this->classKey, array(
'paysys_invoice_id' => $paysys_invoice_id,
'paysystem_id' => $paysystem_id,
))){
return $this->error("Данный счет уже создан в системе.");
}
}
$this->object->addOne($currency);
$this->object->addOne($paysystem);
return parent::beforeSave();
}
/*
Обязательно надо прописывать метод, в котором будет выполняться проверка
подписи с сервера платежной системы
*/
abstract protected function checkSignature();
protected function log($msg, $level = null){
if($level === null){
$level = xPDO::LOG_LEVEL_INFO;
}
$this->modx->log($level, "[Basket - ".__CLASS__."] {$msg}");
$this->modx->log($level, print_r($this->getProperties(), true));
return $msg;
}
protected function error($msg){
return $this->log($msg, xPDO::LOG_LEVEL_ERROR);
}
/*
Логируем все ошибки процессора, на всякий случай
*/
public function failure($msg = '',$object = null) {
$this->error($msg);
if(!empty($this->object) && is_object($this->object)){
$this->error(print_r($this->object->toArray(), true));
}
return parent::failure($msg,$object);
}
public function cleanup() {
/*
// Если оплата прошла успешно, то обновляем статус заказа
*/
if($order_id = $this->object->get('order_id')){
$this->modx->runProcessor('mgr/orders/status/pay', array(
'order_id' => $order_id,
), array(
'processors_path' => $this->BillingProcessorsPath,
));
// На всякий случай сбрасываем счетчик ошибок, если вдруг в вызываемом
// процессоре были ошибки
$this->modx->error->reset();
}
return $this->success($this->getSuccessMessage(), $this->object);
}
protected function getSuccessMessage(){
return '';
}
}
return 'modWebPaymentsCreateProcessor';
<?php
/*
Проводка платежа от робокассы
*/
require_once dirname(dirname(__FILE__)). '/create.class.php';
class modWebPaymentsRobokassaCreateProcessor extends modWebPaymentsCreateProcessor{
public function initialize(){
$this->setProperties(array(
"paysystem_id" => $this->modx->getOption('robokassa.bill_serv_id'),
));
return parent::initialize();
}
/*
Проверяем подпись с робокассы
*/
protected function checkSignature(){
$mrh_pass2 = $this->modx->getOption('robokassa.mrh_pass2');
// Параметры, передаваемые в запросе от робокассы
$crc = mb_strtoupper($this->getProperty('SignatureValue'));
$out_sum = $this->getProperty('OutSum');
$inv_id = $this->getProperty('InvId');
$shp_aid = $this->getProperty('shp_aid');
$shp_order = $this->getProperty('shp_order', null);
$shp_trff = $this->getProperty('shp_trff');
$shp_uid = $this->getProperty('shp_uid');
$my_crc = mb_strtoupper(md5("{$out_sum}:{$inv_id}:{$mrh_pass2}:shp_aid={$shp_aid}:shp_order={$shp_order}:shp_trff={$shp_trff}:shp_uid={$shp_uid}"));
$this->modx->log(xPDO::LOG_LEVEL_INFO, "[Robokassa - robokassa.payResult]", print_r($_REQUEST, true));
// проверка корректности подписи
if ($my_crc !=$crc){
$error = "[Robokassa - robokassa.payResult] - Неверная подпись. Получена: '{$crc}'. Должна быть: '{$my_crc}'";
$this->modx->log(xPDO::LOG_LEVEL_ERROR, $error);
return "bad sign";
}
// else
$this->setProperties(array(
"sum" => $out_sum,
"order_id" => $shp_order,
"owner" => $shp_uid,
"paysys_invoice_id" => $inv_id,
));
return true;
}
protected function getSuccessMessage(){
return 'OK'.$this->getProperty('InvId');
}
}
Из-за участившихся случаев утечек информации с сайтов крупных организаций, наша компания озаботилась защитой и безопасностью сайта и клиентских данных. Первой линией защиты стало внедрение на сайте SMS-подтверждения регистрации и аутентификации.
В этой статье речь пойдет о ресурсе, основанном на CMS ModX. Обеспечивать же безопасность данных пользователей и самого ресурса поможет API-платформа МТС Exolve. Разберемся, что это за сервисы.
Из этого урока Вы узнаете как можно быстро создать RESTful API для любого сайта на любой CMS, MODX — это только пример.
Для создания API я буду использовать: