Это уже интереснее Суть в следующем: предположим вы отдаете файл в формате .avi, но не все, а только лишь некоторые (с) Кличко, могу воспроизводить этот файл. Для того чтобы его можно было смотреть с разных устройств - нужно выполнять конвертацию между форматами. Предположим, что мы живем в мире честных людей, тогда я вижу следующий вариант (комбинация 5 и 2 и 3 метода):
1) Вы делаете скрипт, который выдает hash токен на доступ к определенным файлам. Где-то храните связку - hash и доступных файлов. 2) Делаете скрипт, который через X-Accel-Redirect, при совпадении токена отдает файл.
Таким образом, вы выдаете открытый всем (т.е. его можно подсмотреть в GET-параметрах) hash токен, по которому в течении определенного времени есть доступ к файлу. Например:
Вы выдаете компании X доступ. Пишете hash - 123456789 И определенные файл: bitrix_developer.avi [ID: 1], bitrix_content_manager.avi [ID: 2], bitrix_framework.avi [ID: 3] И говорите: чтобы отдать файл пользователю вы должны отправить его:
noname.com/download.php?file_id=1&hash=123456789
Это отправит пользователя на скачивание bitrix_developer.avi [ID: 1] от компании с хешем: 123456789 Когда истечет токен, он не сможет скачать файл. Полным перебором ID он может скачать все доступные файлы
Вообще решения есть и довольно не простые. По собственному опыту могу сказать что встречал подобные решения и подходы:
1) Отдавать прямую ссылку на файл "как есть", проверяя права только на показ ссылки. Результат: + быстро отдается файл + почти ничего не нужно писать - зная ссылку можно получить файл и без прав
2) Писать страницу на php, которая через readfile будет отдавать контент файла в браузер пользователю Результат: + Нужно писать не так много кода + Контролируется полный скоп прав (можно отобрать права на файл и он станет недоступным) - при большой нагрузке (или больших файлах) сайт умрет
3) Писать страницу на php, которая копирует файл на определенное время и выдает временную ссылку (по истечению X-времени удаляет файл) Результат: + Контролируется полный скоп прав (можно отобрать права на файл и он станет недоступным) + Файл отдается быстро - Зная ссылку на файл, кто угодно может его скачать в течении X времени - Нужно очень много места, т.к. фактически под каждого пользователя (или под каждый запрос) будет копировать файл
4) Написать плагин для nginx, который бы отдавал файл. Результат: + Контролируется полный скоп прав + Быстро отдается файл - Писать много кода на lua, а потом еще и поддерживать
5) Использовать nginx с его X-Accel-Redirect Результат: + Контролируется полный скоп прав + Быстро отдается файл + Не писать много кода - Нужно читать про настройку nginx и X-Accel-Redirect
Если подробнее: 1) Любые изменения из /bitrix/modules/****/classes/*** обернутся против Вас. Это никуда не вынести и никак не "допилить"
2) Возможно часть интересующей функциональности есть в /bitrix/modules/*****/lib/***, тогда вы можете взять исходный класс и отнаследоваться (где возможно) и использовать именно их, однако такое очень большая редкость
Делали что-то подобное (фиксирование голосва - за/против с новым возвращаемым значением - кто не успел проголосовать). Сказу скажу - нормальных хендлеров мы не нашли, поэтому - копируем код активити и в нем уже дописываем кастомный код.
1) Необходимо продумать как вы будете фиксировать в каком блоке какого бп будет происходить логгирование и как вы будете доставать результаты. Это нужно сделать в методе Subscribe. Но опираться нужно на $this->GetWorkflowInstanceId() - потому что многие другие переменные будут утеряны, при голосовании (потеря контекста).
2) Далее фиксировать голоса нужно одновременно в 2х функциях:
- OnExternalEvent - туда попадает все, но при отправки от агента сразу же уходит на другую функцию. Соответственно тут можно и нужно фиксировать голоса за и против.
- ExecuteOnNonApprove - сюда попадает интепретатор в двух случаях - когда кто-то сказал нет и работа блока окончена и когда от агента пришло сообщение об окончании времени голосования.
3) Сами голоса в рамках всего контекта вы можете получить в $this->arApproveResults - ассоциативный массив Пользователь-Голос(true/false) [для всех проголосовавших пользователей] и в OnExternalEvent - $arEventParameters["APPROVE"] или $approve [при голосовании сотрудника]
Андрей Головизнин, вижу, что никто не хочет отвечать на вопрос, а он достаточно интересный по своей сути. Сразу скажу - готового кода тут нет, скорее советы и размышления.
Во-первый, способ который сейчас существует - CFile::GetPath - можете посмотреть как он устроен и в цикле (например foreach) перебирать его значения. В таком случае в самом худшем варианте вы породите N запросов к БД (N - число id файлов в параметре MORE_PHOTO), а в лучшем - зайдете N раз в кеш
Во-вторых, можно сделать быстрый костыльный способ - если сложить upload path (по дефолту - /upload/ ), к нему добавить из БД: SUBDIR, а потом "/", а потом FILE_NAME, то вы можете получить все пути за 1 запрос к БД, но это стоит делать лишь когда вы 100% уверены, что работаете с инфоблоками, что вы НЕ используете облачные хранилища, что файлы у вас именно загружены в инфоблок и что вы сознательно игнорируете событие OnGetFileSRC. Подробнее про получение можно посмотреть тут: http://bxapi.ru/src/?module_id=main&name=CFile::GetFileSRC
Для 2 варианта - если попробуете использовать ORM, дополните его Runtime-полем - "LINK" как результат SQL-комманды CONCAT_WS (погуглите), то можете даже использовать ванильное кеширование - что позволит в лучшем случае даже не делать этого запроса и быстро оперировать сразу путем к файлу
Сергей Сафронов, Судя по обновлению репозитория тестируемая армия 5.2, а значит работать будет до 5.6 включительно (но не гарантируется). 7 внутри от 5 сильно отличается, так что скорее всего не заведется
Евгений Пинчук, В linux через du топ папок в /bitrix/cache/. Например: /bitrix/cache/s1/bitrix/news.list/* - исходя из пути понятно что за сайт и компонент. Если например /bitrix/cache/s29/s29efg.../* - смотрите что в кеше и пытайтесь на основе содержимого понять кто пишет - возможно кастомный код в резалт-модифаера
Сергей Ананьев, попробуйте оставить сервис mysqld и посмотреть что будет запущено - не должно быть никаких mysql*. Если есть - попробуйте убить, затем проверьте доступность сокета (можете попробовать переименовать его), после чего запустить сервис.
И конечно же проверьте подключение из консоли после этих операций
InnoDB: Unable to lock ./ibdata1, error: 11
InnoDB: Check that you do not already have another mysqld process
InnoDB: using the same InnoDB data or log files.
170603 18:47:14 InnoDB: Retrying to lock the first data file
170603 18:47:14 InnoDB: Completed initialization of buffer pool
InnoDB: Unable to lock ./ibdata1, error: 11
InnoDB: Check that you do not already have another mysqld process
InnoDB: using the same InnoDB data or log files.
170603 18:47:14 InnoDB: Retrying to lock the first data file
170603 18:47:14 InnoDB: Completed initialization of buffer pool
InnoDB: Unable to lock ./ibdata1, error: 11
InnoDB: Check that you do not already have another mysqld process
InnoDB: using the same InnoDB data or log files.
170603 18:47:14 InnoDB: Retrying to lock the first data file
У вас точно не запущено 2 mysqld ? например от разных пользователей ? ps aux выдает еще процессы?
Денис Диденко написал: Ядро линукс давно научилось кешировать "горячие" файлы
Не смотря на кеширование, при использовании твердотельных дисков вы ограничены нагрузкой на файловую систему и физическими параметрами (вы не можете читать быстрее чем это позволяет сам жесткий диск). Из оперативки читать все же быстрее.
Цитата
Анатолий Епифанов написал: Техническая поддержка Битрикс рекомендует использовать memcached
Да, только сконфигурировать не забудьте, а то, например при весе кеша 24ГБ (соответственно активного от 4ГБ) держать все это на memcached с выделенным 1GB не рекомендуется, в таком случае файловый кеш будет даже быстрее будет.
Алексей Шафранский, скажите, а bvat уже умеет конфигурировать память под memcached или учитывает это при формировании конфигов от mysql/apache ? А то что-то ни разу не взлетело - везде ручками правим.
Однако ни в методе addOrder, ни в методе NGroupProducts::_construct, ни в методе Query::_construct не происходит инициализация самой $this->init_entity