Telegram Web
Проверка на наличие существующего элемента в инфоблоке по свойству (Битрикс)

Друзья заранее прошу, отнестись к вопросу не очень строго, пишу скрипт первый раз.

Есть 2 инфоблока:

Инфоблок (ID=2) с товарами, там собираю массив с артикулами на WB;
Инфоблок (ID=7) туда добавляю сами отзывы (которые забираю по API).
Функция скрипта: По API получаю отзывы с WB по определенным товарам (по артикулу WB, которые указаны в инфоблоке с товарами) и добавляет элементы в инфоблок с отзывами.

Подскажите пожалуйста как сделать, чтобы при выполнении функции проверялось, на наличие этого отзыва (то есть при повторном запуске скрипта, те что уже есть не добавлялись), у каждого отзыва с WB есть уникальный ID (пример: kzgXM4MB65w5GC7j5vjK), вот по этому свойству элемента инфоблока с отзывами (ID 7) и проверять на существования отзыва.

Заранее всем благодарен за помощь!

<?php
// подключение функций пролога
require($_SERVER["DOCUMENT_ROOT"] . "/bitrix/modules/main/include/prolog_before.php");

set_time_limit(60);

CModule::IncludeModule("main"); // CFile
CModule::IncludeModule("iblock"); // CIBlockElement

$PRODUCT_IBLOCK = '2';
$REVIEWS_IBLOCK = '7';

function getRequestResult($request)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $request);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$headers = array();
$headers[] = 'Content-Type: application/json';
$headers[] = 'Authorization: ........';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
curl_close($ch);
return $result;
}

function parseAndAdd($artnum, $PRODUCT_IBLOCK) {
$org_url = 'https://feedbacks-api.wildberries.ru/api/v1/feedbacks?isAnswered=true&nmId='. $artnum .'&take=5000&skip=0';
$html = getRequestResult($org_url);

$arr = json_decode($html, true);
$counter = 0;

foreach($arr['data']['feedbacks'] as $value){

//Свойства
$PROP = array();
$i = 0;
if (!empty($value['photoLinks'])) {
foreach ($value['photoLinks'] as $morePhoto) {
$arMorePhoto['n'.$i] = array("VALUE"=>CFile::MakeFileArray($morePhoto['fullSize']));
$i++;
}
}
$PROP['ART_WB'] = $value['productDetails']['nmId'];
$PROP['RAITING'] = $value['productValuation'];
$PROP['ISTOCHNIK'] = $value['state'];
$PROP['PHOTO'] = $arMorePhoto;
$PROP['REVIEWSID'] = $value['id'];

//$photolinks[] = $value['photoLinks'];
/*if (!empty($photolinks)) {
foreach($photolinks as $photo){
$photo = $photo['fullSize'];
}
}*/

$el = new CIBlockElement;
$fields = [
'ACTIVE' => "Y",
'IBLOCK_ID' => 7,
"IBLOCK_SECTION_ID" => false,
"NAME" => $value['userName'],
"PREVIEW_TEXT" => $value['text'],
"PREVIEW_PICTURE" => $imgUrl ? CFile::MakeFileArray($imgUrl) : CFile::MakeFileArray($_SERVER["DOCUMENT_ROOT"]."/local/api/wb/avatar.png"),
"PROPERTY_VALUES" => $PROP,
//'ACTIVE_FROM' => $date, // Начало активности
//'DATE_CREATE' => $date, // Дата создания
];

if ($PRODUCT_ID = $el->Add($fields)) {
echo 'Добавлен отзыв, ID: ' . $PRODUCT_ID . '<br />';
$counter++;
} else {
echo "Error[" . $PRODUCT_ID . "]: " . $el->LAST_ERROR . '<br />';
}

}

echo 'Отзывы по товару с артикулом '.$artnum . ' добавлены. Количество '. $counter. '<br>';

}

//print_r($photo);
//print_r(parseAndAdd(113509876, 6));
$places_ids = []; // Храню артикулы всех товаров, по которым будет забирать отзывы
$arSelect = ["NAME","PROPERTY_ART_WB"];
$arFilter = ["IBLOCK_ID" => $PRODUCT_IBLOCK,"ACTIVE" => "Y",];
$resp = CIBlockElement::GetList(Array(), $arFilter, false, false, $arSelect);
while($ob = $resp->GetNextElement()) {
$arFields = $ob->GetFields(); // Получаю значения полей элемента
$places_ids[] = $arFields['PROPERTY_ART_WB_VALUE']; // Заполняю массив с артикулами
}

foreach ($places_ids as $arrwb) {
if (!empty($arrwb)) {
parseAndAdd($arrwb, 7);
}
}
?>
Подключение скриптов и стилей на уровень выше корневой директории

Пытаюсь реализовать собственную cms для своего сайта в качестве практики php, но столкнулся со следующей проблемой (Картинка)
Имеется иерархия проекта описанная выше. В папке core основные важные скрипты, по типу базового контроллера, подключения к БД и др, В папке develop находятся пользовательские контроллеры, представления, модели и шаблоны В папке public только .htaccess, index.php который вызывает bootstrap.php из core и иконка сайта

При нужном url я вызываю требуемый контроллер и подключаю:

шапку сайта
представление
подвал сайта
но мне очень нравится идея с шаблонами, и понравилась bitrix структура шаблонов, поэтому я хотел бы сделать это и у себя. Шаблоны, как я и писал выше, хранятся в /develop/templates. Корневая директория сайта /public/

Пробовал относительные пути по совету ChatGPT и людей с форумов, не помогает

(../../develop/...)
Пробовал реализовать перенаправление в htaccess

RewriteCond %{REQUEST_URI} ^/templates/admin/(.*)$
RewriteCond %{REQUEST_URI} !/develop/templates/(.*)$
RewriteRule ^(.*)$ http://%{HTTP_HOST}/../templates/$1 [L,R=301]
но пока что ничего не помогает, а хранить шаблоны в public мне не очень нравится...

Собственно, вопрос: Можно ли реализовать подключение стилей, скриптов, картинок через php и htaccess, не затрагивая конфиг файл httpd? Пока что видел только такое решение, но хотел бы его избежать, чтобы сайт был легк переносим.

P.S. Забыл написать, что также нашел решение

echo '<style>';
include <путь к стилю>
echo '</style>';
Насколько такое решение будет... Неправильным, при создании шаблонов?
Ошибка Call to undefined function mysqli_connect()

Не могу подключить базу данных к сайту. При попытке подключить БД выдаётся такая ошибка:

Fatal error: Uncaught Error: Call to undefined function mysqli_connect() in D:\Проекты\Новая папка\index.php:11 Stack trace: #0 {main} thrown in D:\Проекты\Новая папка\index.php on line 11

У меня OC Windows 11

Вот мой код:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<p>Не работает php</p>
<?php
$connection=mysqli_connect('localhost', 'root', '', 'data');
$sql = "SELECT Name FROM tablical";
$massive=mysqli_query($connection, $sql);
$data=mysqli_fetch_assoc($massive);
foreach ($data as $key => $value) {
print_r($value);
}
?>



</body>
</html>
Авторизация действий над определенными полями на основе ролей и разрешений

Использую пакет spatie-permission, Laravel 11.У юзера есть permission формата entity.action.value, например - order.edit.description(редактировать описание заказа) или order.see.Accepted (видеть заказы со статусом Accepted). У меня появились две идеи как это авторизовать: первая - написать кастомное правило валидации и применить к каждому полю в FormRequset:

public function validate(string $attribute, mixed $value, Closure $fail): void
{
if (!Gate::allows($this->action,[$attribute,auth()->user()])){
$fail('You do not have permission to interact with this field.');
}
}
Gate:

Gate::define('order-edit-field', function (User $user,string $attribute): bool {
return (in_array($attribute,$user->convertPermissionToValue('order.edit')) || $user->isAdmin());
});
Идея в чем - все разрешения обрезаются с помощью convertPermissionToValue() до value , и это value сравнивается с пришедшем с реквеста полем.

Вторая мысль - через политики:

public function update(User $user, Order $order,array $data): bool
{
if ($user->isAdmin()){
return true;
}

$fields = $user->convertPermissionToValue('order.edit');
$statuses = $user->convertPermissionToValue('order.view');
return in_array($order->status,$statuses)
&& array_reduce(array_keys($data),function ($accum, $item ) use ($fields){
return in_array($item,$fields) && $accum;
},true);
}
Сравнивается .value и fields реквеста, если какого то field нет в value - 403. Таким же образом проверяются любые действия над сущностями - permissions обрезаются до value, value сравнивается с полями ,со статусами, и вообще с чем угодно ,над чем нужно будет совершить action.

В чем собственно говоря вопрос: хоть один из этих вариантов - так вообще норм делать ? Сколько бы не гуглил, я не смог найти как именно организовать авторизацию действий над конкретными полями. Есть какие примеры реализации такого, как бы это вы сделали, где разумно было бы делать подобные проверки, хорошая ли вообще идея с convert разрешений, рабочая ли идея с такими составными permission. Буду ооочень благодарен за любую помощь или подсказку, ибо я новичок и даже те два примера выше выдались огромными нервозатратами)
Ищешь полезные знания по архитектуре PHP-приложений?

Подключайся к онлайн-конференции Podlodka PHP Crew, которая пройдет с 30 сентября по 4 октября!

Получишь практические кейсы и советы от экспертов с опытом реальных внедрений в крупных проектах.

💡Ключевые спикеры сезона:

🔥 Кирилл Мокевнин, сооснователь Hexlet, научит строить код на базе явного состояния и флагового программирования, от простых регистраций до сложной синхронизации данных.

💡 Валентин Удальцов, opensource-разработчик, объяснит, когда стоит внедрять CQRS и как избежать ненужных сложностей.

💳 Дмитрий Кириллов, CTO 1С-Старт, разберет ошибки в банковских интеграциях и покажет, как проектировать качественные API на PHP.

📊 Алексей Солодкий из BelkaCar покажет, как использовать Prometheus для кастомных метрик и организовать мониторинг PHP-приложений.

Не упусти шанс улучшить свои навыки! Подробности и билеты на сайте: https://podlodka.io/phpcrew
🐘 Тест по PHP

Проверь насколько хорошо ты знаешь PHP

Ответишь — пройдешь на продвинутый курс "PHP Developer. Professional" от OTUS по специальной цене + получишь чек-лист "Solid и типичные ошибки на собеседованиях" .

👉 ПРОЙТИ ТЕСТ: https://clck.ru/3DPRMP

Приятный бонус Курс можно приобрести в рассрочку и без переплаты

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
Please open Telegram to view this post
VIEW IN TELEGRAM
Качество кода, архитектуры. Service and Repository pattern. PHP & Laravel

Стремлюсь к очень качественному коду, посоветоваться не с кем. Вычитал очень много про архитектуру и пришел к этому (Пример на PHP Laravel)

Middleware - Прослойка запроса, проверка аутентификации и подобного, если это необходимо

FormRequest - Тут мы делаем валидацию запроса(Если это не GET)

Controller - тут мы принимаем запрос, делаем валидацию, если FormRequest не предусмотрен, отдаем это всё в Service и затем отдаём ответ

Service - Тут вся бизнес логика, обращение к Repository

ServiceInterface - интерфейс для нашего Service, для гибкости кода

Repository - логика обращения к базе данных, модели, все запросы и т д

RepositoryInterface - интерфейс для Repository, так же для гибкости

Затем мы регистрируем наши интерфейсы и их реализацию в ServiceProvider и работаем по такой архитектуре.

Хотел спросить - всё ли верно, не излишне ли, стоит ли добавить какой то шаг или же убрать. Спасибо
v📢 Приглашение на открытый вебинар: Архитектор 1С и "сложные" проекты - как помочь заказчику стартовать?

Часто проекты не начинаются или "топчутся" на месте из-за полученных заказчиком оценок стоимости/трудоемкости реализации всех его требований. Как архитектор может помочь запустить проект?

🌟 На открытом уроке рассмотрим:
1. Какое влияние архитектор 1С может оказать в проектах с разным подходом (монолит/лоскутная/иные подходы)?
2. Какую стратегию на сложном проекте выбрать, если заказчик хочет взять паузу?
3. Риски, с которыми можем столкнуться в компаниях с историческими системами.

Вебинар будет полезен:
Аналитикам и разработчикам 1С, руководителям проектов, начинающим архитекторам.

В результате вебинара:
Определим варианты работы с заказчиками на проектах - как архитектор может помочь руководителю проекта стартовать проект и какие варианты запуска предложить.

Присоединяйтесь к открытому вебинару 24 сентября в 19:00 мск и сделайте этот прыжок в будущее!

Запишитесь на вебинар и прокачайте свои навыки работы с архитектурой 1С: https://clck.ru/3DPPbP

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
🔥 Пройди тест по Laravel ! 🔥

➡️ Проверь себя и свои знания. Сможешь сдать — пройдёшь на продвинутый курс "Framework Laravel" от OTUS по специальной цене.

👩‍💻 Присоединяйся к новому потоку онлайн-курса «Framework Laravel» в OTUS. В программе курса — удобные и мощные наработки огромного Laravel-сообщества, а практика — решение бизнес-задач.

👨‍💻 За 3 месяца обучения твое портфолио пополнится мини-проектами и выпускной работой.

Приятный бонус Курс можно приобрести в рассрочку и без переплаты

👉 ПРОЙТИ ТЕСТ

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
Please open Telegram to view this post
VIEW IN TELEGRAM
Как устроена реализация в играх кликерах обработка и сохранение кликов в бд?

Каждый клик допустим это +N монет. Отправлять при каждом клике на фронте событие в виде простого запроса на бэк, где инкрементируется значение в бд - очевидное и простое решение, но будет высокая нагрузка на бэк. Поэтому интересно как лучше всего решать задачи подобного плана и какие инструменты использовать.

Я так понимаю для таких задач нужен какой то демон на сервере собирающий события пользователей о кликах в оперативке и после интервально сохранять в БД подсчитав и проверив данные, так как хранить на фронте даже шифруя наверное будет опрометчиво и при желании можно будет обмануть сервер? Какими инструментами лучше решать эту задачу? nginx push stream, socketio nodejs или есть еще варианты?

Буду благодарен за любую подсказку, может статью которая задевает этот технический аспект, ну и названия пакетов\допов для веб-сервера.
Один источник данных для множества каналов

Всем привет.

Не уверен, что правильно указал название. Сейчас столкнулся с тем, что нужно раздавать данные из одного источника многим. Схема такая

Источник->Раздающий скрипт->Потребители

То есть, я получаю по вебсокету и по curl определенные данны. По вебсокету бегут постоянно, по curl более статичные. Мне нужно, желающим, эти данные отдавать не неся нагрузку на Источник. То есть Источник только предоставляе их одному сайту, а тот сайт уже раздает другим.

Вопрос в том, как правильно организовать раздачу вебсокета, если к Источнику я могу подключить только один канал?

Я с вебсокетом работал только в простом варианте - получить, отправить и т.д.
👩‍💻 Приглашаем на открытый урок «Динамичный фронтэнд на PHP с Laravel Livewire».

📆 Дата и время: 2 октября в 20:00 мск

Участие бесплатное

Вебинар состоится в рамках онлайн-курса «Framework Laravel» в OTUS.

В ходе занятия мы рассмотрим:

➡️ Возможности Laravel Livewire.
➡️ Создание приложения с использованием Livewire с нуля.

Продолжить изучение фреймворка вы сможете на курсе, который можно приобрести в рассрочку.

👉 Регистрируйтесь прямо сейчас, чтобы не пропустить урок: https://clck.ru/3DUUyd

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Please open Telegram to view this post
VIEW IN TELEGRAM
🐘 Тест по PHP

Проверь насколько хорошо ты знаешь PHP, ты начинающий junior или крепкий Middle?

Ответишь — сможешь пройти на продвинутый курс "PHP Developer. Professional" от OTUS по специальной цене + получишь чек-лист "Solid и типичные ошибки на собеседованиях" .

👉 ПРОЙТИ ТЕСТ: https://clck.ru/3DWpFq

Приятный бонус Курс можно приобрести в рассрочку и без переплаты

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
Please open Telegram to view this post
VIEW IN TELEGRAM
laravel pusher не работает почему то отправка

'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => env('PUSHER_APP_CLUSTER'),
'host' => env('PUSHER_HOST') ?: 'api-'.env('PUSHER_APP_CLUSTER', 'mt1').'.pusher.com',
'port' => env('PUSHER_PORT', 443),
'scheme' => env('PUSHER_SCHEME', 'https'),
'encrypted' => true,
'useTLS' => env('PUSHER_SCHEME', 'https') === 'https',
],
'client_options' => [
// Guzzle client options: https://docs.guzzlephp.org/en/stable/request-options.html
],
],
Файл конфигурации не трогал просто добавлял в env креды ,на прямую креды работают если использовать

public function sendTestMessage()
{
$options = [
'cluster' => env('PUSHER_APP_CLUSTER'),
'useTLS' => true
];
$pusher = new Pusher(
env('PUSHER_APP_KEY'),
env('PUSHER_APP_SECRET'),
env('PUSHER_APP_ID'),
$options
);

$data['message'] = 'hello world';
$pusher->trigger('test-channel', 'my-event', $data);

return response()->json(['message' => 'Event has been sent!']);
}
Отправляю Event после того как создал заказ но сам event не приходит в pusher Debug Console

Использую laravel 11
Highload, системный дизайн, производительность и масштабирование

Приглашаем на курс для прокачки навыков архитектора и проектировщика, которые важны для профессионального роста программиста.

🌐 С курсом «Системный дизайн высоконагруженных проектов» вы:

▪️изучите ключевые фундаментальные паттерны и получите навыки проектирования проектов с миллионной аудиторией (балансировка, масштабирование апп/кешей/субд, высокая доступность и кластерные решения, шардинг, CAP/PACELS, консистентность, саги, транзакционные очереди и многое другое)
▪️поупражняетесь в проектировании и получите обратную связь на реальных задачах: магазин/маркетплейс, такси/доставка, обьявления, соцсети, дейтинг, игры, википедия, мессенжер, CDN, хранилище файлов, онлайн-кинотеатр, счетчики, удаленный мониторинг, интеграционные вебхуки, рассылки и тд.
▪️ научитесь планировать нагрузку и связывать
бизнес-показатели с нефункциональными требованиями к системе
▪️ попрактикуемся в проведении и прохождения секций системного дизайна на интервью

Всё в формате «живых» онлайн-сессий (лекции, брейнштормы, презентации домашних проектов).

🥸 Кто мы: школа Devhands, основатель школы и автор курса Алексей Рыбак, ex-СТО Badoo, с 20-летним опытом высоконагруженных проектов и и управления глобальными технологическими организациями, член программного комитета Highload.

🗓 Старт 22-го октября, изучаем программу, записываемся здесь

Реклама. ИП Рыбак А.А. ИНН 771407709607 erid: 2VtzqvS4wkM
Please open Telegram to view this post
VIEW IN TELEGRAM
Разделить список директории на дочерние и родительские

Подскажите правильное направление или пример. Есть список:

$list = ['folder', 'folder2','folder2/items','folder2/items/css','folder2/images'];
Нужно получить многомерный массив с дочерними элементами:

$list = [
["name" => "folder", "path" => "/folder", children: []],
["name" => "folder2", "path" => "/folder2", children:
[
"name" => "items", "path" => "/folder2/items", children:
[
"name" => "css", "path" => "folder2/items/css", children: []
],
"name" => "images", "path" => "/folder2/images", children: [],
]
],
];
👩‍💻 Актуальное повышение квалификации для PHP-разработчиков

Пройди тест по Laravel !

➡️ Проверь себя и свои знания. Сможешь сдать — пройдёшь на продвинутый курс "Framework Laravel" от OTUS по специальной цене.

👨‍💻 За 3 месяца обучения твое портфолио пополнится мини-проектами и выпускной работой.

Приятный бонус Курс можно приобрести в рассрочку и без переплаты

➡️ ПРОЙТИ ТЕСТ: https://clck.ru/3DcR2F

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
Please open Telegram to view this post
VIEW IN TELEGRAM
Bitrix24 вызов попапа посредством события в inti.php

В init.php прописываю событие, которое должно открывать попап после сообщения в открытых линиях, само событие отрабатывает, в лог пишет. Но попап в CRM не открывается. Вот само событие:

AddEventHandler("imopenlines", "OnSessionStart", "OnFirstMessage");
function OnFirstMessage($arFields) {
$chatId = $arFields['CHAT_ID']; // Логируем ID чата в файл для дальнейшей обработки
file_put_contents(__DIR__."/test.txt", $chatId . PHP_EOL, FILE_APPEND);
\Bitrix\Main\Page\Asset::getInstance()->addString('
<div id="openline_confirm"></div>');
\Bitrix\Main\Page\Asset::getInstance()->addString('
<script>
BX.ready(function() {
var Confirmer = new BX.PopupWindow("openline_confirm", null, {
content: "<div></div>" + "<h3>Новое сообщение в открытых линиях</h3>",
closeIcon: {
right: "20px",
top: "20px"
},
width: 350, // ширина окна
height: 150, // высота окна
zIndex: 100, // z-index
draggable: false, // можно двигать или нет
resizable: true, // можно ресайзить
min_height: 250, // минимальная высота окна
min_width: 100, // минимальная ширина окна
overlay: {
backgroundColor: "black",
opacity: "80"
},
buttons: [
new BX.PopupWindowButton({
text: "Принять",
className: "popup-window-button-accept",
events: {
click: function() {
BX.Messenger.Public.openLines();
this.popupWindow.close();
}
}
}),
new BX.PopupWindowButton({
text: "Отклонить",
className: "webform-button-link-cancel",
events: {
click: function() {
this.popupWindow.close();
}
}
})
]
});
Confirmer.show();
});
</script>');
CJSCore::Init(array("Confirmer"));
}
При событии js на стороне клиента не добавляется, как это можно реализовать?
2024/10/02 10:24:27
Back to Top
HTML Embed Code: