SYAN

SYAN

С нами с 22 февраля 2017; Место в рейтинге пользователей: #399
29 января 2026, 11:29
+1
код для генерации схем MIGXdb
может кому пригодится или доработается
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>XML Generator for MIGX (Table View)</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 20px;
            color: #333;
        }
        .config-group {
            margin-bottom: 20px;
            padding: 15px;
            border: 1px solid #ddd;
            border-radius: 6px;
            background-color: #f9f9f9;
        }
        .config-group label {
            display: block;
            margin: 8px 0 4px;
            font-weight: bold;
            font-size: 0.9em;
        }
        .config-group input {
            width: 100%;
            padding: 8px;
            border: 1px solid #ccc;
            border-radius: 4px;
            box-sizing: border-box;
        }
        .mjg_input_rows {
            width: 100%;
            border-collapse: collapse;
            margin-bottom: 20px;
        }
        .mjg_input_rows th {
            background-color: #f2f2f2;
            text-align: left;
            padding: 12px;
            font-weight: bold;
            border: 1px solid #ddd;
        }
        .mjg_input_rows td {
            padding: 10px;
            border: 1px solid #ddd;
            vertical-align: top;
        }
        .mjg_input_field input,
        .mjg_input_caption input,
        .mjg_input_inputTVtype select {
            width: 100%;
            padding: 8px;
            border: 1px solid #ccc;
            border-radius: 4px;
            box-sizing: border-box;
        }
        .mjg_input_showintabs label,
        .mjg_input_sortable label {
            display: flex;
            align-items: center;
            gap: 5px;
        }
        .mjg_input_deleterow_action {
            color: #dc3545;
            cursor: pointer;
            font-weight: bold;
        }
        .mjg_input_rows_add_wr {
            margin: 15px 0;
        }
        .mjg_input_rows_add {
            display: inline-block;
            background: #28a745;
            color: white;
            padding: 10px 15px;
            border-radius: 4px;
            cursor: pointer;
            font-size: 0.9em;
        }
        .mjg_input_rows_add:hover {
            background: #218838;
        }
        textarea {
            width: 100%;
            height: 300px;
            font-family: monospace;
            padding: 12px;
            border: 1px solid #ccc;
            border-radius: 4px;
            resize: vertical;
            box-sizing: border-box;
            margin-top: 10px;
            font-size: 0.95em;
        }
        h1 {
            color: #2c3e50;
            margin-bottom: 20px;
        }
        /* Стили для выпадающего списка опций (скрыт по умолчанию) */
        .mjg_input_inputTVtype_inputOptionValues {
            margin-top: 8px;
            display: none;
        }
        .mjg_input_inputTVtype_inputOptionValues_item {
            display: flex;
            gap: 8px;
            margin-bottom: 5px;
        }
        .mjg_input_inputTVtype_inputOptionValues_item input {
            flex: 1;
            padding: 6px;
        }
        .mjg_input_inputTVtype_inputOptionValues_item_delete {
            color: #dc3545;
            cursor: pointer;
            font-weight: bold;
        }
        .mjg_input_inputTVtype_inputOptionValues_add {
            color: #007bff;
            cursor: pointer;
            font-size: 0.85em;
            margin-top: 5px;
        }
    </style>
</head>
<body>
    <h1>Генератор XML для MIGX/MODX (Таблица)</h1>

    <!-- Основные настройки модели -->
    <div class="config-group">
        <label for="modelPackage">Package (model package)</label>
        <input type="text" id="modelPackage" value="mygallery" placeholder="Например: mygallery">

        <label for="objectClass">Class (object class)</label>
        <input type="text" id="objectClass" value="myGallery" placeholder="Например: myGallery">


        <label for="tableName">Table (table)</label>
        <input type="text" id="tableName" value="migx_gallery" placeholder="Например: migx_gallery">
    </div>

    <div class="mjg_input_rows">
        <table>
            <thead>
                <tr>
                    <th>Ключ (key)
<span style="font-size:12px;color:#888;">Например: title</span></th>
                    <th>Тип БД (dbtype)
<span style="font-size:12px;color:#888;">varchar, int и др.</span></th>
                    <th>Точность (precision)
<span style="font-size:12px;color:#888;">Для varchar/int</span></th>
                    <th>PHP-тип (phptype)
<span style="font-size:12px;color:#888;">string, integer и др.</span></th>
                    <th>NULL?</th>
                    <th>Значение по умолчанию</th>
                    <th>Индекс</th>
                    <th></th>
                </tr>
            </thead>
            <tbody id="fieldsContainer">
                <!-- Первая строка по умолчанию -->
                <tr class="mjg_input_row" id="field_1">
                    <td class="mjg_input_field">
                        <input type="text" name="key" placeholder="title" required>
                    </td>
                    <td class="mjg_input_dbtype">
                        <select name="dbtype" onchange="updatePhpType(this)">
                            <option value="varchar">varchar</option>
                            <option value="text">text</option>
                            <option value="int">int</option>
                            <option value="datetime">datetime</option>
                            <option value="tinyint">tinyint</option>
                            <option value="json">json</option>
                        </select>
                    </td>
                    <td class="mjg_input_precision">
                        <input type="text" name="precision" placeholder="255">
                    </td>
                    <td class="mjg_input_phptype">
                        <select name="phptype" required>
                            <option value="string">string</option>
                            <option value="integer">integer</option>
                            <option value="datetime">datetime</option>
                            <option value="json">json</option>
                        </select>
                    </td>
                    <td class="mjg_input_null">
                        <label><input type="checkbox" name="null" checked> Да</label>
                    </td>
                    <td class="mjg_input_default">
                        <input type="text" name="default" placeholder="0">
                    </td>
                    <td class="mjg_input_index">
                        <select name="index">
                            <option value="">—</option>
                            <option value="index">index</option>
                            <option value="fulltext">fulltext</option>
                                                        <option value="unique">unique</option>
                        </select>
                    </td>
                    <td class="mjg_input_deleterow">
                        <span class="mjg_input_deleterow_action" onclick="removeField('field_1')">X</span>
                    </td>
                </tr>
            </tbody>
        </table>
        <div class="mjg_input_rows_add_wr">
            <div class="mjg_input_rows_add" onclick="addField()">Добавить строку</div>
        </div>
    </div>

    <!-- Кнопка генерации XML -->
    <div style="margin: 20px 0;">
        <button type="button" onclick="generateXML()" style="
            background: #007bff;
            color: white;
            border: none;
            padding: 10px 20px;
            border-radius: 4px;
            cursor: pointer;
            font-size: 1em;
        ">Сгенерировать XML</button>
    </div>

    <h2>Результат (XML)</h2>
    <textarea id="output" placeholder="Здесь появится сгенерированный XML..." readonly></textarea>

    <script>
        let fieldCount = 1; // Начинаем с 1, т.к. первая строка уже есть

        function addField() {
            fieldCount++;
            const container = document.getElementById('fieldsContainer');

            const newRow = document.createElement('tr');
            newRow.className = 'mjg_input_row';
            newRow.id = `field_${fieldCount}`;

            newRow.innerHTML = `
                <td class="mjg_input_field">
                    <input type="text" name="key" placeholder="title" required>
                </td>
                <td class="mjg_input_dbtype">
                    <select name="dbtype" onchange="updatePhpType(this)">
                        <option value="varchar">varchar</option>
                        <option value="text">text</option>
                        <option value="int">int</option>
                        <option value="datetime">datetime</option>
                        <option value="tinyint">tinyint</option>
                        <option value="json">json</option>
                    </select>
                </td>
                <td class="mjg_input_precision">
                    <input type="text" name="precision" placeholder="255">
                </td>
                <td class="mjg_input_phptype">
                    <select name="phptype" required>
                        <option value="string">string</option>
                        <option value="integer">integer</option>
                        <option value="datetime">datetime</option>
                        <option value="json">json</option>
                    </select>
                </td>
                <td class="mjg_input_null">
                    <label><input type="checkbox" name="null" checked> Да</label>
                </td>
                <td class="mjg_input_default">
                    <input type="text" name="default" placeholder="0">
                </td>
                <td class="mjg_input_index">
                    <select name="index">
                        <option value="">—</option>
                        <option value="index">index</option>
                        <option value="fulltext">fulltext</option>
                        <option value="unique">unique</option>
                    </select>
                </td>
                <td class="mjg_input_deleterow">
                    <span class="mjg_input_deleterow_action" onclick="removeField('field_${fieldCount}')">X</span>
                </td>`;

            container.appendChild(newRow);
        }

        function removeField(id) {
            const el = document.getElementById(id);
            if (el) el.remove();
        }

        function updatePhpType(selectEl) {
            const dbtype = selectEl.value;
            const row = selectEl.closest('tr');
            const phptypeSelect = row.querySelector('select[name="phptype"]');


            let suggestedType = 'string';
            switch (dbtype) {
                case 'int':
                case 'tinyint':
                    suggestedType = 'integer';
                    break;
                case 'datetime':
                    suggestedType = 'datetime';
                    break;
                case 'json':
                    suggestedType = 'json';
                    break;
            }
            phptypeSelect.value = suggestedType;
        }

        function escapeXml(str) {
            if (typeof str !== 'string') return '';
            return str
                .replace(/&/g, '&')
                .replace(/</g, '<')
                .replace(/>/g, '>')
                .replace(/"/g, '"')
                .replace(/'/g, ''');
        }

        function generateXML() {
            // Получаем основные параметры
            const modelPackage = escapeXml(document.getElementById('modelPackage').value.trim() || 'mytable');
            const objectClass = escapeXml(document.getElementById('objectClass').value.trim() || 'myTable');
            const tableName = escapeXml(document.getElementById('tableName').value.trim() || 'migx_table');

            const rows = document.querySelectorAll('#fieldsContainer tr.mjg_input_row');
            const xmlLines = [];

            // Заголовок XML
            xmlLines.push('<?xml version="1.0" encoding="UTF-8"?>');
            xmlLines.push(`<model package="${modelPackage}" baseClass="xPDOObject" platform="mysql" defaultEngine="MyISAM" version="1.1">`);
            xmlLines.push(`    <object class="${objectClass}" table="${tableName}" extends="xPDOSimpleObject">`);


            // Обработка каждой строки таблицы
            rows.forEach(row => {
                const keyInput = row.querySelector('input[name="key"]');
                const key = keyInput ? keyInput.value.trim() : '';

                // Пропускаем строку, если ключ не указан
                if (!key) {
                    console.warn('Пропущена строка без ключа:', row);
                    return;
                }

                let fieldXml = `        <field key="${escapeXml(key)}"`;

                const dbtype = row.querySelector('select[name="dbtype"]').value;
                if (dbtype) fieldXml += ` dbtype="${escapeXml(dbtype)}"`;

                const precision = row.querySelector('input[name="precision"]').value.trim();
                if (precision) fieldXml += ` precision="${escapeXml(precision)}"`;

                const phptype = row.querySelector('select[name="phptype"]').value;
                if (phptype) fieldXml += ` phptype="${escapeXml(phptype)}"`;

                const nullCheckbox = row.querySelector('input[name="null"]');
                const nullVal = nullCheckbox.checked ? 'true' : 'false';
                fieldXml += ` null="${nullVal}"`;

                const defaultVal = row.querySelector('input[name="default"]').value.trim();
                if (defaultVal) fieldXml += ` default="${escapeXml(defaultVal)}"`;

                const indexVal = row.querySelector('select[name="index"]').value;
                if (indexVal) fieldXml += ` index="${escapeXml(indexVal)}"`;
                
                fieldXml += ' />';
                xmlLines.push(fieldXml);
            });

            // Добавляем стандартные агрегации
            xmlLines.push('        <aggregate alias="Resource" class="modResource" local="resource_id" foreign="id" cardinality="one" owner="foreign" />');
            xmlLines.push('        <aggregate alias="Creator" class="modUser" local="createdby" foreign="id" cardinality="one" owner="foreign" />');


            // Закрывающие теги
            xmlLines.push('    </object>');
            xmlLines.push('</model>');


            // Выводим результат в текстовое поле
            document.getElementById('output').value = xmlLines.join('\n');
        }

        // Инициализация: добавляем обработчик для кнопки генерации
        document.addEventListener('DOMContentLoaded', () => {
            document.querySelector('.mjg_input_rows_add').addEventListener('click', addField);
        });
    </script>
</body>
</html>
22 мая 2025, 22:41
0
тот же вопрос по диапозону дат. готового решения так никто и не озвучит?
06 мая 2025, 20:21
0
решил таким способом получение первой картинки
{set $preview = $_modx->runSnippet('ms2Gallery', [
			'resources' => $id,
            'filetype' => 'image', 
            'limit' => 1,
            'tpl' => '@FILE chunks/image_url.tpl'            
            ])}
chunks/image_url.tpl
{if $files?}
{foreach $files as $file}
{$file['medium']}
{/foreach}
{/if}
18 апреля 2025, 00:03
0
Не работает парсинг с vk.com, vkvideo.ru
16 апреля 2025, 11:39
0
Не выводятся товары привязанные к данной категории, как дополнительной
В админке они отображаются в обеих категориях, опубликованы, кэши сняты
Showlog также их не видит

{'!msProducts' | snippet : [
            'parents' => $_modx->resource.id,
            ]}
MODX 3.1.2-pl
MiniShop3 — 1.0.0-alpha
22 января 2024, 13:49
0
стоит добавить в сниппете 'isfolder' => 0
$items = $pdo->getCollection('modResource', array(
    'published' => true,
    'deleted' => false,
    'isfolder' => 0
21 января 2024, 16:15
0
Это сниппет для создания списка с алфавитным указателем
15 декабря 2023, 00:09
0
Не смог разобраться, как удалять и генерировать по одному из ключей настроек источника файлов
У меня два типа превью small и medium
{
"small":{"wp":150,"wl":150,"q":90,"f":"webp"},
"medium":{"wp":350,"wl":350,"q":80,"f":"jpg"}
}
Если необходимо добавить еще один тип или изменить настройки одного из типов, то при выполнении данного кода удаляются все файлы превью обоих типов и пересоздаются заново
$child->remove();
generateThumbnails();
Есть ли возможность пересоздать конкретный?
20 мая 2022, 01:16
0
решено
запуск сниппета в head
<?php
$getid = $_GET['id'];
if ($getid != '' && is_numeric($getid)) { 
    $url=$modx->makeUrl($modx->getOption('id', $scriptProperties, $modx->resource->get('id')));
    header('HTTP/1.1 301 Moved Permanently');
    header('Location: '.$url.'');
    echo '<meta http-equiv="refresh" content="0;URL='.$url.'"/>'; }
25 апреля 2022, 19:45
0
Нашел. ../assets/components/onebooking/js/web/default.js в конце задать minDate и MaxDate в формате yyyy-mm-d
25 апреля 2022, 18:14
0
необходима помощь с one booking, покупал вместе с one period. из магазина оно пропало как и переписка с автором в формате поддержки

Отсутствовала возможность ограничить выборку в календаре по датам. Отель работал толко в летнее время, поэтому необходимо было выставить даты с 01.06.2021 по 30.09.2021
На момент сдачи проекта вручную указал начальную и конечную дату для календаря 2021 года.
прошел год. Пришло время ввести новые даты и хоть убей не помню где я их менял…
Заметки остались в переписке с автором
Сам проект и поддержка через modxstore недоступны
27 ноября 2021, 01:40
0
все еще актуально, буду признателен
17 ноября 2021, 18:39
0
разобрался. проблема была в переносе с сервера на сервер
17 ноября 2021, 12:46
0
Аналогичная дилемма, не могу «достучаться» до small и medium

{'!pdoPage' | snippet : [
	'element' => 'msProducts',
	'parents' => '840',
	'limit' => '5',
	'offset' => '0',
	'depth' => '10',
	'tvPrefix' => '',
	'select' => 'pagetitle, id, small, medium'
	'includeThumbs' => 'small, medium',
	'tpl' => '@INLINE id={$id} sm={$small} med={$medium} th={$thumb}
',
	'showLog' => '1'
]}
id=1270 sm= med= th=/assets/images/gallery/1270/small/scale-1200.jpg
id=1271 sm= med= th=/assets/images/gallery/1271/small/maxresdefault-(1).jpg
id=1272 sm= med= th=/assets/images/gallery/1272/small/fffff1.jpg
id=1276 sm= med= th=/assets/images/gallery/1276/small/0-02-05-5d02719d25c310d2fab855d57d513acfe4d9210fc4cacd93b04859c68b064021-ba4aa39157e0f880.jpg
id=1278 sm= med= th=/assets/images/gallery/1278/small/image-17-05-21-06-53.jpg
0.0002019: pdoTools loaded.
0.0067320: Conditions prepared
0.0000679: xPDO query object created
0.0003850: leftJoined msProductData as Data
0.0002551: leftJoined msVendor as Vendor
0.0035899: leftJoined msProductFile as small
0.0002770: leftJoined msProductFile as medium
0.0000079: Grouped by msProduct.id, `small`.url, `medium`.url
0.0000529: Added selection of msProduct: SQL_CALC_FOUND_ROWS `id`, `type`, `contentType`, `pagetitle`, `longtitle`, `description`, `alias`, `alias_visible`, `link_attributes`, `published`, `pub_date`, `unpub_date`, `parent`, `isfolder`, `introtext`, `richtext`, `template`, `menuindex`, `searchable`, `cacheable`, `createdby`, `createdon`, `editedby`, `editedon`, `deleted`, `deletedon`, `deletedby`, `publishedon`, `publishedby`, `menutitle`, `donthit`, `privateweb`, `privatemgr`, `content_dispo`, `hidemenu`, `class_key`, `context_key`, `content_type`, `uri`, `uri_override`, `hide_children_in_tree`, `show_in_tree`, `properties`
0.0000269: Added selection of msProductData: `article`, `price`, `old_price`, `weight`, `image`, `thumb`, `vendor`, `made_in`, `new`, `popular`, `favorite`, `tags`, `color`, `size`, `source`
0.0000231: Added selection of msVendor: `name` AS `vendor.name`, `resource` AS `vendor.resource`, `country` AS `vendor.country`, `logo` AS `vendor.logo`, `address` AS `vendor.address`, `phone` AS `vendor.phone`, `fax` AS `vendor.fax`, `email` AS `vendor.email`, `description` AS `vendor.description`, `properties` AS `vendor.properties`
0.0000350: Added selection of msProductFile: url as `small`
0.0000160: Added selection of msProductFile: url as `medium`
0.0012341: Processed additional conditions
0.0018170: Added where condition: class_key=msProduct, msProduct.parent:IN(840,1278,1279,1280), OR:msProduct.id:IN(1270,1271,1272,1276,2445,2674,3319,3326,3327,3360,3361), msProduct.published=1, msProduct.deleted=0
0.0001121: Sorted by msProduct.id, ASC
0.0000029: Limited to 5, offset 0
0.0004950: SQL prepared "SELECT SQL_CALC_FOUND_ROWS `msProduct`.`id`, `msProduct`.`type`, `msProduct`.`contentType`, `msProduct`.`pagetitle`, `msProduct`.`longtitle`, `msProduct`.`description`, `msProduct`.`alias`, `msProduct`.`alias_visible`, `msProduct`.`link_attributes`, `msProduct`.`published`, `msProduct`.`pub_date`, `msProduct`.`unpub_date`, `msProduct`.`parent`, `msProduct`.`isfolder`, `msProduct`.`introtext`, `msProduct`.`richtext`, `msProduct`.`template`, `msProduct`.`menuindex`, `msProduct`.`searchable`, `msProduct`.`cacheable`, `msProduct`.`createdby`, `msProduct`.`createdon`, `msProduct`.`editedby`, `msProduct`.`editedon`, `msProduct`.`deleted`, `msProduct`.`deletedon`, `msProduct`.`deletedby`, `msProduct`.`publishedon`, `msProduct`.`publishedby`, `msProduct`.`menutitle`, `msProduct`.`donthit`, `msProduct`.`privateweb`, `msProduct`.`privatemgr`, `msProduct`.`content_dispo`, `msProduct`.`hidemenu`, `msProduct`.`class_key`, `msProduct`.`context_key`, `msProduct`.`content_type`, `msProduct`.`uri`, `msProduct`.`uri_override`, `msProduct`.`hide_children_in_tree`, `msProduct`.`show_in_tree`, `msProduct`.`properties`, `Data`.`article`, `Data`.`price`, `Data`.`old_price`, `Data`.`weight`, `Data`.`image`, `Data`.`thumb`, `Data`.`vendor`, `Data`.`made_in`, `Data`.`new`, `Data`.`popular`, `Data`.`favorite`, `Data`.`tags`, `Data`.`color`, `Data`.`size`, `Data`.`source`, `Vendor`.`name` AS `vendor.name`, `Vendor`.`resource` AS `vendor.resource`, `Vendor`.`country` AS `vendor.country`, `Vendor`.`logo` AS `vendor.logo`, `Vendor`.`address` AS `vendor.address`, `Vendor`.`phone` AS `vendor.phone`, `Vendor`.`fax` AS `vendor.fax`, `Vendor`.`email` AS `vendor.email`, `Vendor`.`description` AS `vendor.description`, `Vendor`.`properties` AS `vendor.properties`, `small`.url as `small`, `medium`.url as `medium` FROM `modx_site_content` AS `msProduct` LEFT JOIN `modx_ms2_products` `Data` ON `msProduct`.`id` =  `Data`.`id` LEFT JOIN `modx_ms2_vendors` `Vendor` ON Data.vendor=Vendor.id LEFT JOIN `modx_ms2_product_files` `small` ON `small`.product_id = msProduct.id AND `small`.rank = 0 AND `small`.path LIKE '%/small/%' LEFT JOIN `modx_ms2_product_files` `medium` ON `medium`.product_id = msProduct.id AND `medium`.rank = 0 AND `medium`.path LIKE '%/medium/%' WHERE  ( `msProduct`.`class_key` = 'msProduct' AND  ( `msProduct`.`parent` IN (840,1278,1279,1280) OR `msProduct`.`id` IN (1270,1271,1272,1276,2445,2674,3319,3326,3327,3360,3361) )  AND `msProduct`.`published` = 1 AND `msProduct`.`deleted` = 0 )  GROUP BY msProduct.id, `small`.url, `medium`.url ORDER BY msProduct.id ASC LIMIT 5 "
0.0307870: SQL executed
0.0004852: Total rows: 14
0.0001588: Rows fetched
0.0002320: Returning raw data
0.0039260: Checked the active modifiers
0.0100322: Created inline "modChunk" with name "155f451b34a1811dc72be7d50b156266"
0.0091128: Compiled Fenom chunk with name "modchunk/155f451b34a1811dc72be7d50b156266"
0.0147741: Time to load products options
0.0754728: Total time
4 194 304: Memory usage
06 ноября 2021, 18:02
0
Прошу прощения, не углядел заголовок. Автору респект, но буду искать иное решение или плагин
05 ноября 2021, 18:08
0
увидел что-то до боли похожее в готовых решениях modx.pro/solutions/18899 но выскакивает ошибка при инициализации плагина, кнопка не отображается
Данный плагин, а также typograf поддерживают только tiny 1.4, а в репозитории стандартно 2.03
Для работы требуется установка более ранней версии редактора. Автор не удосужился описать совместимость

И может кто знает, как разместить галерею и редактор контента для редактирования товара на одной странице, как на видео работы р=плагина у автора? возможно можно просто решить задачу перетаскиванием в окно редактора?
У автора стандартная панель галереи редактирования обычного ресурса (не минишоп)
Драг-н-дроп не поддерживает
01 ноября 2021, 22:42
0
Возможно, картина не в RGB, а в CMYK
На сайте выводится картинка оригинал, а в админке используется миниатюра созданная phpThumb, и вот он не понимает CMYK и инвертирует подобные изображения
Переконвертируйте картинку и залейте заново
Была как-то подобная проблема. Ничем другим не лечится :)
13 апреля 2021, 11:08
0
ну и не забываем включить jquery на сайте
12 апреля 2021, 23:33
0
предлагаю рабочее решение pdoPage под fenom с загрузкой ajax

<div id="pdopage">
    <div class='row'>
	{'!pdoPage' | snippet : [
		'parents' => '0',
		'limit' => '10',
		...			
		'toPlaceholder' => 'result',
		'ajaxMode' => 'button',
                'ajaxElemWrapper' => '#pdopage'
                'ajaxElemRows' => '#pdopage .row'
                'ajaxElemPagination' => '#pdopage .pagination'
                'ajaxTplMore' => '@INLINE <div class="text-center"><button class="btn btn-primary btn-more">Загрузить еще</button></div>'
	]}
        {'result' | placeholder}			
    </div>
     {'page.nav' | placeholder}
</div>
23 марта 2017, 01:49
0
Упсь, обознатушки… не всё. зашел под другим аккаунтом. из 16 ресурсов повторно предлагает проголосовать за 3.

что то не так здесь с проверкой проголосовавших…

лично у меня доверий к этому скрипту нет :(