Для вывода одинакового для всех картинок текста можно просто накладывать png с подготовленным как надо текстом. Просто я не вижу необходимости динамически внедрять в картинку текст. Подписать можно и в слое, наложенном на картинку средствами html/css.
При наложении текста на изображение средствами библиотеки phpThumb/modPhpThumb (фильтр «wmt») текст выглядит коряво (размер — 8-12px, шрифты проверял Arial и Calibri). Вероятно, при наложении текста не используется сглаживание. Соответствующих настроек у phpThumb/modPhpThumb нет. Шрифт используется не системный, а непосредственно указываемый (параметр «f» фильтра «wmt») Посоветуйте, как получить сглаженный текст на изображении? P.S. Да и вообще, не понимаю, как сглаживать текст в php средствами gd и imageMagick… Есть 2 функции/метода: ImageTTFtext() — параметров, отвечающих за сглаживание, нет Imagick::annotateImage() — параметров, отвечающих за сглаживание, нет
Добавляйте пользователя в группу Administrator с ролью SuperUser. Но это все равно не гарантирует полные права на все и вся. Для надеги поставьте галочку Sudo (Неограниченные права).
Извиняюсь за примитивный вопрос, но в сети не нашел инфы. Политика доступа и роли — это все непонятно. Нужно создать аккаунт админа, чтобы заходить через сайт/manager. Админ, у которого был бы полный доступ, логин и пароль. Управление -> Пользователи -> Новый пользователь
Мне довольно часто приходится формировать совсем не простые запросы к БД, и не редко xPDO не позволяет просто так составить нужный запрос. В процессе я нарыл весьма глубинный способ формировать нужные запросы с вложенными подзапросами. Вот один из таких примеров (который в общих чертах попадет в новую сборку ShopModxBox, которую я так давно обещаю и кто-то уже устал ждать). <?php
require_once MODX_CORE_PATH . 'components/billing/processors/mgr/orders/grid/getlist.class.php';
class ShopOrdersGetlistProcessor extends modMgrOrdersGridGetlistProcessor{
public function prepareQueryBeforeCount(xPDOQuery $c){
$c = parent::prepareQueryBeforeCount($c);
$alias = $c->getAlias();
$where = array();
if($status = (int)$this->getProperty('status')){
$where['status_id'] = $status;
}
if($contractor = (int)$this->getProperty('contractor')){
$where['contractor'] = $contractor;
}
if($date_from = $this->getProperty('date_from')){
$where['createdon:>='] = date('Y-m-d H:i:s', strtotime($this->getProperty('date_from')));
}
if($date_from = $this->getProperty('date_till')){
$where['createdon:<='] = date('Y-m-d H:i:s', strtotime($this->getProperty('date_till')));
}
if($where){
$c->where($where);
}
if($search = $this->getProperty('search')){
$word = $this->modx->quote("%{$search}%");
$q = $this->modx->newQuery('OrderProduct');
$q->innerJoin('ShopmodxProduct', 'Product');
$q->innerJoin('modResource', 'ResourceProduct', "ResourceProduct.id = Product.resource_id");
$q_alias = $q->getAlias();
$q->select(array(
"{$q_alias}.order_id",
));
$order_id = (int)$search;
$q->where(array(
"order_id = {$alias}.id
AND (order_id = {$order_id}
OR ResourceProduct.pagetitle LIKE {$word}
OR ResourceProduct.longtitle LIKE {$word}
OR ResourceProduct.content LIKE {$word}
)",
));
$q->prepare();
$sql = $q->toSQL();
# print $sql;
$c->where(array(
"ContractorProfile.phone LIKE {$word}",
));
$c->query['where'][] = new xPDOQueryCondition(array(
'sql' => "EXISTS ({$sql})",
'conjunction' => "OR",
));
}
return $c;
}
}
return 'ShopOrdersGetlistProcessor'; Советую особое внимание обратить на параметр 'conjunction' => «OR». Этот запрос позволяет выполнить поиск заказов с учетом дат, id заказа, пользователя, заголовков/контента товаров и т.п.
Вот итоговый SQL: SELECT
Order
.*,
Order
.id as order_id,
Status.status as status_str,
(
select
sum(op.price * op.quantity)
from modx_billing_order_products
op
where op.order_id = Order.id
) as sum,
Payment.id as pay_id,
Payment.paysys_invoice_id,
Payment.date as pay_date,
Payment.sum as pay_sum,
Paysystem.name as paysystem_name,
ContractorProfile.fullname as contractor_fullname,
ContractorProfile.email as contractor_email,
if(ContractorProfile.mobilephone != '', ContractorProfile.mobilephone, ContractorProfile.phone) as contractor_phone,
ManagerProfile.fullname as manager_fullname,
Status
.id
AS status_id
,
Status
.status
AS status_status
,
Status
.color
AS status_color
,
Status
.rank
AS status_rank
,
Status
.comment
AS status_comment
FROM modx_billing_orders
AS Order
JOIN modx_billing_order_statuses
Status
ON Order
.status_id
= Status
.id
LEFT JOIN modx_billing_payments
Payment
ON Payment.order_id = Order.id
LEFT JOIN modx_billing_paysystems
Paysystem
ON Payment.paysystem_id = Paysystem.id
LEFT JOIN modx_users
Contractor
ON Order
.contractor
= Contractor
.id
LEFT JOIN modx_user_attributes
ContractorProfile
ON Contractor.id=ContractorProfile.internalKey
LEFT JOIN modx_users
Manager
ON Order
.manager
= Manager
.id
LEFT JOIN modx_user_attributes
ManagerProfile
ON Manager.id=ManagerProfile.internalKey
WHERE (
(
(
Order
.createdon
>= '2015-09-27 00:00:00' AND Order
.createdon
<= '2015-10-07 00:00:00'
)
AND ContractorProfile.phone LIKE '%980%'
)
OR EXISTS (
SELECT OrderProduct.order_id
FROM modx_billing_order_products
AS OrderProduct
JOIN modx_shopmodx_products
Product
ON OrderProduct
.product_id
= Product
.id
JOIN modx_site_content
ResourceProduct
ON ResourceProduct.id = Product.resource_id
WHERE order_id = Order.id
AND (order_id = 980
OR ResourceProduct.pagetitle LIKE '%980%'
OR ResourceProduct.longtitle LIKE '%980%'
OR ResourceProduct.content LIKE '%980%'
)
)
) Другой вариант этого же запроса: <?php
require_once MODX_CORE_PATH . 'components/billing/processors/mgr/orders/grid/getlist.class.php';
class ShopOrdersGetlistProcessor extends modMgrOrdersGridGetlistProcessor{
public function prepareQueryBeforeCount(xPDOQuery $c){
$c = parent::prepareQueryBeforeCount($c);
$alias = $c->getAlias();
$where = array();
if($status = (int)$this->getProperty('status')){
$where['status_id'] = $status;
}
if($contractor = (int)$this->getProperty('contractor')){
$where['contractor'] = $contractor;
}
if($date_from = $this->getProperty('date_from')){
$where['createdon:>='] = date('Y-m-d H:i:s', strtotime($this->getProperty('date_from')));
}
if($date_from = $this->getProperty('date_till')){
$where['createdon:<='] = date('Y-m-d H:i:s', strtotime($this->getProperty('date_till')));
}
if($where){
$c->where($where);
}
if($search = $this->getProperty('search')){
$word = $this->modx->quote("%{$search}%");
$q = $this->modx->newQuery('OrderProduct');
$q->innerJoin('ShopmodxProduct', 'Product');
$q->innerJoin('modResource', 'ResourceProduct', "ResourceProduct.id = Product.resource_id");
$q_alias = $q->getAlias();
$q->select(array(
"{$q_alias}.order_id",
));
$order_id = (int)$search;
$q->where(array(
"order_id = {$alias}.id
AND (order_id = {$order_id}
OR ResourceProduct.pagetitle LIKE {$word}
OR ResourceProduct.longtitle LIKE {$word}
OR ResourceProduct.content LIKE {$word}
)",
));
$q->prepare();
$sql = $q->toSQL();
$c->query['where'][] = new xPDOQueryCondition(array(
'sql' => "ContractorProfile.phone LIKE {$word}",
));
$c->query['where'][] = new xPDOQueryCondition(array(
'sql' => "EXISTS ({$sql})",
'conjunction' => "OR",
));
}
return $c;
}
}
return 'ShopOrdersGetlistProcessor'; Формирует тот же самый запрос. Отличие только в том, что заменили конструкцию $c->where(array( "ContractorProfile.phone LIKE {$word}", )); на $c->query['where'][] = new xPDOQueryCondition(array( 'sql' => "ContractorProfile.phone LIKE {$word}", )); Здесь конструкций EXISTS более предпочтительна, чем обычный JOIN, так как у на записи не уникальные (Заказ и Товары заказа — связь один-ко-многим). EXISTS выполняет промежуточный поиск и возвращает по прежнему уникальные записи из основной таблицы. А если джоинить, то получим не уникальные записи. UPD: В предыдущей версии запроса были логические ошибки. Кто скажет какие — молодца! :) Исправленная версия запроса с улучшениями: <?php
require_once MODX_CORE_PATH . 'components/billing/processors/mgr/orders/grid/getlist.class.php';
class ShopOrdersGetlistProcessor extends modMgrOrdersGridGetlistProcessor{
public function prepareQueryBeforeCount(xPDOQuery $c){
$c = parent::prepareQueryBeforeCount($c);
$alias = $c->getAlias();
$where = array();
if($status = (int)$this->getProperty('status')){
$where['status_id'] = $status;
}
if($contractor = (int)$this->getProperty('contractor')){
$where['contractor'] = $contractor;
}
if($date_from = $this->getProperty('date_from')){
$where['createdon:>='] = date('Y-m-d H:i:s', strtotime($this->getProperty('date_from')));
}
if($date_from = $this->getProperty('date_till')){
$where['createdon:<='] = date('Y-m-d H:i:s', strtotime($this->getProperty('date_till')));
}
if($where){
$c->where($where);
}
if($search = $this->getProperty('search')){
$word = $this->modx->quote("%{$search}%");
$q = $this->modx->newQuery('OrderProduct');
$q->innerJoin('ShopmodxProduct', 'Product');
$q->innerJoin('modResource', 'ResourceProduct', "ResourceProduct.id = Product.resource_id");
$q_alias = $q->getAlias();
$q->select(array(
"{$q_alias}.order_id",
));
$order_id = (int)$search;
$q->where(array(
"order_id = {$alias}.id
AND (order_id = {$order_id}
OR ResourceProduct.pagetitle LIKE {$word}
OR ResourceProduct.longtitle LIKE {$word}
OR ResourceProduct.content LIKE {$word}
)",
));
$q->prepare();
$sql = $q->toSQL();
# print $sql;
$conditions = [];
if($phone = preg_replace('/[^\+0-9\-\(\)]/', '', $search)){
$phone = $this->modx->quote("%{$phone}%");
$conditions[] = new xPDOQueryCondition(array(
'sql' => "REPLACE(ContractorProfile.phone, ' ', '') LIKE {$phone}",
));
}
$conditions[] = new xPDOQueryCondition(array(
'sql' => "EXISTS ({$sql})",
'conjunction' => $conditions ? "OR" : "AND",
));
$c->query['where'][] = $conditions;
# $c->prepare();
# print $c->toSQL();
}
return $c;
}
}
return 'ShopOrdersGetlistProcessor'; Результат: SELECT
Order
.*,
Order
.id as order_id,
Status.status as status_str,
(
select sum(op.price * op.quantity)
from modx_billing_order_products
op
where op.order_id = Order.id
) as sum,
Payment.id as pay_id,
Payment.paysys_invoice_id,
Payment.date as pay_date,
Payment.sum as pay_sum,
Paysystem.name as paysystem_name,
ContractorProfile.fullname as contractor_fullname,
ContractorProfile.email as contractor_email,
if(ContractorProfile.mobilephone != '', ContractorProfile.mobilephone, ContractorProfile.phone) as contractor_phone,
ManagerProfile.fullname as manager_fullname,
Status
.id
AS status_id
,
Status
.status
AS status_status
,
Status
.color
AS status_color
,
Status
.rank
AS status_rank
,
Status
.comment
AS status_comment
FROM modx_billing_orders
AS Order
JOIN modx_billing_order_statuses
Status
ON Order
.status_id
= Status
.id
LEFT JOIN modx_billing_payments
Payment
ON Payment.order_id = Order.id
LEFT JOIN modx_billing_paysystems
Paysystem
ON Payment.paysystem_id = Paysystem.id
LEFT JOIN modx_users
Contractor
ON Order
.contractor
= Contractor
.id
LEFT JOIN modx_user_attributes
ContractorProfile
ON Contractor.id=ContractorProfile.internalKey
LEFT JOIN modx_users
Manager
ON Order
.manager
= Manager
.id
LEFT JOIN modx_user_attributes
ManagerProfile
ON Manager.id=ManagerProfile.internalKey
WHERE (
( Order
.createdon
>= '2015-09-27 00:00:00' AND Order
.createdon
<= '2015-10-07 00:00:00' )
AND
(
REPLACE(ContractorProfile.phone, ' ', '') LIKE '%253140%'
OR EXISTS (
SELECT OrderProduct.order_id
FROM modx_billing_order_products
AS OrderProduct
JOIN modx_shopmodx_products
Product
ON OrderProduct
.product_id
= Product
.id
JOIN modx_site_content
ResourceProduct
ON ResourceProduct.id = Product.resource_id
WHERE order_id = Order.id
AND (order_id = 253140
OR ResourceProduct.pagetitle LIKE '%253140%'
OR ResourceProduct.longtitle LIKE '%253140%'
OR ResourceProduct.content LIKE '%253140%'
)
)
)
)
интересное решение… вам плюс
Если бы вы не были авторизованы (в том числе в админке), вам бы эта информация не выводилась.
joxi.ru/Dr8y1EXUXOeOm6 тут я не админ пока еще )
Вы авторизованы как админ, вот вам и выводится во фронт отладочная информация. Отключите плагин Debug и не будет. joxi.ru/eAOqaVNfYPL8mo