Задать вопрос
  • Централизованное обновление нескольких сайтов?

    mramor
    @mramor
    нечего о себе рассказывать.
    Была аналогичная проблема. Гит проблему не решал, ибо все на шаредах, на одном нам гит врубили, но хостов прорва, более 60 проектов. Кароче, на каждый клянчить гит не получилось. Пришлось писать приложение на пайтоне, который синхронизировал все остальные с мастер-хостом по сфтп. Также с БД, писал файл инструкций, который выполнялся на каждом хосте с ссш, также скриптами.
    Ну и докучи был написан пхп скрипт анализа баз данных после всех изменений, на случай если что-то пойдет не так, который брал базу мастер хоста, паковал ее структуру в массив и после проверялось на наличие\отсутствие полей\таблиц по всем бд. Весь скрипт выкладывать не буду, но сбор бд в массив делал так:

    function createStruct($shop){
        
        if(!isset($shop['db'])) return false;
        $tablesArray = array();
        
        $link = mysql_connect($shop['db']['host'], $shop['db']['user'], $shop['db']['password']);
        mysql_select_db($shop['db']['name'], $link);
        
        $resultTables = mysql_query("show tables", $link);
        if(mysql_affected_rows($link) > 0){
            while($table = mysql_fetch_array($resultTables)){
                    $tablesArray[$table[0]] = array();
            }        
        }
        
        if(empty($tablesArray)) return false;
        
        foreach($tablesArray as $tableName => $tmpval){
            $resultFields = mysql_query('DESCRIBE '.$tableName, $link); 
            if(mysql_affected_rows($link) > 0){
                while($rowField = mysql_fetch_assoc($resultFields)){
                    $tablesArray[$tableName][$rowField['Field']] = array(
                        'type'  => $rowField['Type'],
                        'null'  => $rowField['Null'],
                        'key'   => $rowField['Key'],
                        'default' => $rowField['Default'],
                        'extra' => $rowField['Extra']
                    
                    );
                }
            }       
        }
        
        mysql_close($link);
        return $tablesArray;    
    }

    Код не идеален, но за идеальностью и не гнался.

    Вот часть обработки сверки:
    $ideal = createStruct($shops[0]);
        
        $equal = createStruct($shops[$_SESSION['sc']]);
        
        if($equal === false || empty($equal)){
            $html = '<table><tr><td><h3>Проблемы с подключение к базе сайта <b>'.$s->shop_name.'</b>, возможно база не была создана, либо не верные коды доступа, либо прекратила свое существование.</h3></td></tr></table>';
        }else{
        
        $html = '<table>';
        $html .= '<tr><td><h3>'.$s->shop_name.'</h3></td></tr>';
        foreach($ideal as $table => $fields){
            if(!isset($equal[$table])){
                $html .= '<tr><td>Отсутствует таблица <b>'.$table.'</b></td></tr>';
            }else{
                $html .= '<tr><td>';
                    foreach($ideal[$table] as $key => $fieldRow){
                        if(!isset($equal[$table][$key])){
                            $html .= 'В таблице <b>'.$table.'</b> не хватает поля <b>'.$key.'</b><br>';
                        }else{
                            foreach($ideal[$table][$key] as $okey => $oval){
                                if($equal[$table][$key][$okey] !== $oval){
                                    
                                    $text = $equal[$table][$key][$okey];
                                    if($equal[$table][$key][$okey] === NULL){
                                        $text = 'NULL';
                                    }elseif($equal[$table][$key][$okey] === ''){
                                        $text = ' (ПУСТОТА) ';
                                    }elseif($equal[$table][$key][$okey] === TRUE){
                                        $text = 'TRUE';
                                    }elseif($equal[$table][$key][$okey] === FALSE){
                                        $text = 'FALSE';
                                    }
                                    
                                    $html .= 'Опции поля <b>'.$key.'</b> в таблице <b>'.$table.'</b> не идентичны. Идеал: '.$oval.' Исследуемый: '.$text.'<br>';
                                }
                            }
                        }
                    }
                
                $html .= '</td></tr>';
            }
            
            if(isset($equal[$table])){
                unset($equal[$table]);
                unset($ideal[$table]);
            }
        }
    Ответ написан
    5 комментариев
  • Как ускорить реакцию на нажатие ссылок в WebView под Android?

    vdstudio
    @vdstudio Автор вопроса
    Огромное спасибо!
    Правда, я не использовал приведенный там код двум причинам:
    1) этот код не решает проблему с фантомными кликами (на одно событие происходит два клика)
    1) у меня за основу взят jQuery и мне не хотелось бороться с совместимостью.
    Но, потянув за ниточку в одном из комментариев, нашел плагин к jQuery, который замечательно работает (по-крайней мере на моем ViewSonic под Android 2.2)
    Может, кому еще пригодится:

    /**
    * jQuery.fastClick.js
    *
    * Work around the 300ms delay for the click event in some mobile browsers.
    *
    * Code based on <code.google.com/mobile/articles/fast_buttons.html>
    *
    * @usage
    * $('button').fastClick(function() {alert('clicked!');});
    *
    * @license Under Creative Commons Attribution 3.0 License
    * @author Dave Hulbert (dave1010)
    * @version 0.2 2011-09-20
    */

    /*global document, window, jQuery, Math */

    (function($) {

    $.fn.fastClick = function(handler) {
    return $(this).each(function(){
    $.FastButton($(this)[0], handler);
    });
    };

    $.FastButton = function(element, handler) {
    var startX, startY;

    var reset = function() {
    $(element).unbind('touchend');
    $(document.fastButton).unbind('touchmove');
    };

    var onClick = function(event) {
    event.stopPropagation();
    reset();
    handler.call(this, event);

    if (event.type === 'touchend') {
    $.clickbuster.preventGhostClick(startX, startY);
    }
    };

    var onTouchMove = function(event) {
    if (Math.abs(event.originalEvent.touches[0].clientX - startX) > 10 ||
    Math.abs(event.originalEvent.touches[0].clientY - startY) > 10) {
    reset();
    }
    };

    var onTouchStart = function(event) {
    event.stopPropagation();

    $(element).bind('touchend', onClick);
    $(document.fastButton).bind('touchmove', onTouchMove);

    startX = event.originalEvent.touches[0].clientX;
    startY = event.originalEvent.touches[0].clientY;
    };

    $(element).bind({
    touchstart: onTouchStart,
    click: onClick
    });
    };

    $.clickbuster = {
    coordinates: [],

    preventGhostClick: function(x, y) {
    $.clickbuster.coordinates.push(x, y);
    window.setTimeout($.clickbuster.pop, 2500);
    },

    pop: function() {
    $.clickbuster.coordinates.splice(0, 2);
    },

    onClick: function(event) {
    var x, y, i;
    for (i = 0; i < $.clickbuster.coordinates.length; i += 2) {
    x = $.clickbuster.coordinates[i];
    y = $.clickbuster.coordinates[i + 1];
    if (Math.abs(event.clientX - x) < 25 && Math.abs(event.clientY - y) < 25) {
    event.stopPropagation();
    event.preventDefault();
    }
    }
    }
    };

    $(function(){
    document.addEventListener('click', $.clickbuster.onClick, true);
    });

    }(jQuery));
    Ответ написан
    Комментировать