• Как связаться с пользователем сайта?

    Я так понял, вы со мной хотели связаться? Извините, Масим, у меня нет возможности сейчас заниматься приватными консультациями или брать новые проекты.
    Ответ написан
  • Возможно ли с помощью Node.js/php получить скрытый контент определенной странице определенного сайта?

    Я обычно пользуюсь DOM в PHP. Конечно, можно отдельные поля регулярными выражениями отловить, если знаешь их название, но есть большая вероятность, что у одного инпута сначала будет идти `type`, потом `name`, а у другого наоборт, и придётся для каждого инпута писать отдельный код, который будет из него вытаскивать значение. Проще воспринимать их как сущности с одинаковыми признаками и переложить парсинг на специализированные билиотеки.

    Насколько я понял, судя по особенностям наименования инпутов, это был форум на базе hoop.la (не путать с hoopla). Я бы примерно так организовал парсинг:

    $dom = new \DOMDocument();
    
    libxml_use_internal_errors(true);
    if (!@$dom->loadHTML('содержимое страницы в виде HTML')) {
        /** @var \LibXMLError $error */
        $error = libxml_get_last_error();
        if ($error->level > LIBXML_ERR_ERROR) {
            throw new \Exception($error->message);
        }
    }
    
    $xpath = new \DOMXPath($dom);
    
    /** @var \DOMNodeList $form */
    $form = $xpath->query('//form[@name="mainLoginForm"]');
    if (!$form->length) {
        throw new \Exception('Форма не найдена');
    }
    
    $post_data = [];
    
    /** @var \DOMElement $input */
    foreach ($xpath->query('.//input', $form->item(0)) as $input) {
        $post_data[$input->getAttribute('name')] = $input->getAttribute('value');
    }
    
    $post_data['email'] = 'логин';
    $post_data['password'] = 'пароль';
    
    // В $post_data находятся все данные которые нужно отправлять


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

    В каких-то других ситуациях, кроме инпутов нужно будет искать ещё и селекты, или предусматривать ситуации, когда нужно делать выбор из нескольких radio-элементов, либо предусматривать ещё более комплексные ситуации, но конкретно в случае с hoopla этого не потребуется — там одни инпуты, и они динамически с помощью JS вроде бы не модифицируются (сильно не тестировал).

    Код может быть нерабочим. Я его наполовину копипастил из собственных разработок, наполовину писал прямо на Тостере. Главное, из него понятен смысл.
    Ответ написан
  • Как поймать момент выбора вкладки?

    У TabControl есть событие GotFocus (само событие относится к родительскому Control, и доступно для всех потомков Control. Для того же TabControl, например).

    Как я понимаю, вы вообще не сталкивались с таким понятием, как «события», потому что думаете в рамках «бесконечных циклов» для отлова каких-то обстоятельств.

    Советую почитать что-нибудь, относящееся к событийно-ориентированному программированию (event-driven development). Я не говорю, что нужно программировать в этом стиле, но если вы почитаете что-нибудь, относящееся к такому подходу, вам будет проще понимать, что такое «события» и как их можно использовать в обычной работе.
    Ответ написан
  • Где искать агента на upwork?

    Я уже поздно попал в этот вопрос, когда уже появился выбранный ответ. Но, мне кажется, при наличии хорошего портфолио лучше всё-таки подаваться на Toptal, а не на Upwork. На Toptal больше шансов поработать, например, на J.P.Morgan, Airbnb или Axel Springer AG. Опять же, насколько я знаю, там клиенты чаще ориентируются на долгие и сложные проекты, по сравнению со среднестатиcтической биржей.

    Регистрироваться и проходить собеседования (несколько собеседований при регистрации — проверка разговорного английского, проверка профессиональных навыков) там придётся каждому фрилансеру индивидуально, но, я думаю, проблем с тем, чтобы работать командой, там быть не должно.

    На Тостере, кстати, бывает Dmitry Pavlov — он рекрутёром работает в Totpal. У него можно много дополнительной информации узнать. В целом, Toptal больше подходит на роль агентства, чем Upwork.
    Ответ написан
  • Как в Yii запустить Yii::app()->runController в isAjaxRequest блоке?

    Ничего не генерируется, потому что ничего не возвращается. Самый простой способ:

    public function actionCreate()
    {
        $model = new Hotels();
    
        /**
         * @todo Something
         */
    
        if (Yii::app()->request->isAjaxRequest) {
            Yii::app()->end(json_encode($model->getAttributes()));
        }
    
        $this->render('create', ['model' => $model]);
    }


    При вызове метода end() в качестве первого параметра можно указать любые данные, которые нужно отправить в браузер. Если не указывать, то приложение просто завершится и, при обычных условиях, ничего не отправится.

    Дополнительно,
    Yii::app()->runController('sadmin/hotels/update/id/1416')
    никак не влияет на вывод потому что не делает никаого эха. Если он что-то будет выводить, то это тоже отправится в браузер. Но с вашим кодом это эхо ещё и с нормальный рендером смешается, если будет не-AJAX-запрос.

    Либо, если вы уверены, что «sadmin/hotels/update/id/1416» что-то выводит:

    public function actionCreate()
    {
        if (Yii::app()->request->isAjaxRequest) {
            ob_start();
            Yii::app()->runController('sadmin/hotels/update/id/1416');
            Yii::app()->end(ob_get_clean());
        }
    
        $model = new Hotels();
    
        $this->render('create', ['model' => $model]);
    }


    Я могу в каких-то мелочах ошибаться, потому что с первой версией Yii мало работал, но, думаю, идея понятна.
    Ответ написан
  • Как убрать id категорий из url opencart?

    Если вам не хочется вручную редактировать SEO URL для большого количества категорий, найдите на бирже фрилансеров специалиста, который готов этим заняться. Стандартными средствами опенкарта нельзя пакетно редактировать SEO-алиасы категорий.

    Отдельная заметка для Максим Каракулов: Я тусуюсь на Тостере только тогда, когда у меня есть свободное время и желание отвечать на чьи-то вопросы. Когда мне в почту падает сообщение, что кто-то меня приглашает ответить на вопрос, я считаю это спамом. Я не вижу способа отключить уведомления о том, что кто-то приглашает меня ответить как эксперта без того, чтобы не нарушить остальные уведомления на почту. Я считаю это большим косяком Тостера. Не вижу возможности выбирать, какие именно уведомления я хочу видеть в почте, а какие уведомления должны оставаться в рамках интерфейса сайта.
    Ответ написан
  • Насколько сильно облегчились условия работы для разработчиков/тестеров и т.п. по сравнению с 1960-1970 годами?

    Условия облегчились в 42 раза по сравнению с 60-70-ми годами. Если не верите и хотите пересчитать самостоятельно, советую почитать книгу Гленфорда Майерса — «Надёжность программного обеспечения» — Издательство «Мир». Москва, 1980. Почти треть книги посвящена тестированию. Там (что мне нравится в старых книгах) очень много ссылок и на другие книги, если вдруг заинтересует эта тема. В университетской библиотеке можно найти. Я свой экземпляр именно так и «нашёл» сколько-то лет назад.

    Вкратце, в те года к тестированию был более научный подход, были всякие методологии, было намного больше видов тестирования и требовалось больше мыслить. Сейчас для тестирования часто пользуются готовыми библиотеками. Раньше тестирование было процессом, явно нацеленным на поиск ошибок. Сейчас тестирование — это, скорее, создание набора спецификаций для программы, которым она должна соответствовать. Если сделать небольшое допущение, то тесты сегодня — это то же самое, что технические задания вчера. Поэтому естественно, что сейчас условия стали в 42 раза легче.

    Ну, и всякие штуки, вроде удобных кресел, свободного графика, кучи информации в Интернете, которую легко прогуглить и пр. — это тоже облегчает работу.
    Ответ написан
  • Как получить access_token для facebook на python?

    У вас ведь на серверной стороне всё это происходит — значит никто не увидит ваш FACEBOOK_APP_SECRET. Значит можно сделать так (см. документацию):

    oauth_access_token = "|".join([FACEBOOK_APP_ID, FACEBOOK_APP_SECRET])


    There is another method to make calls to the Graph API that doesn't require using a generated app token. You can just pass your app id and app secret as the access_token parameter when you make a call:
    Ответ написан
  • Как правильно сравнить массивы и оценить их схожесть?

    Если два массива имеют одинаковую длину, можно просто двигать по кругу первый массив и сравнивать его элементы с элементами второго. Потом можно просто выбрать максимальное совпадение и перегнать в проценты. Примерно так:

    $arr1 = [1,2,3,4,5,7,2,8];
    $arr2 = [2,9,5,5,7,2,8,1];
    
    $len = count($arr1);
    $conformity = [];
    
    for($i = 0; $i < $len; $i++) {
    	/**
    	 * $temp содержит нули в позициях, где числа в двух массивах 
    	 * по одному и тому же индексу не равны. Единицы — там, где равны.
    	 */
    	$temp = array_map(function($x,$y){return intval($x==$y);}, $arr1, $arr2);
    	
    	// Элементы полученного массива суммируются и добавляются в отчётный массив
    	$conformity[] = array_sum($temp);
    	
    	// Массив прокручивается на одну позицию
    	$arr1[] = array_shift($arr1);
    }
    
    //С помощью max($conformity) выбирается максимальное совпадение элементов
    echo sprintf("Max conformity is %s%%\n", number_format(100*(max($conformity)/$len), 2));


    Это конкретно для ситуации, когда длина «колец» одинаковая.

    Update: ещё один вариант:

    $arr1 = [1,2,3,4,5,7,2,8];
    $arr2 = [2,9,5,5,7,2,8,1];
    
    function conformity($arr1, $arr2) {
    	$len = count($arr1);
    	$max = $curr = 0;
    	
    	for($i = 0; $i < $len; $i++) {
    		array_map(function($x,$y)use(&$curr){$curr += intval($x==$y);}, $arr1, $arr2);
    		
    		if($curr == $len) {
    			return 100;
    		}
    
    		$max = $max > $curr ? $max : $curr;
    		$curr = 0;
    		
    		$arr1[] = array_shift($arr1);
    	}
    	
    	return 100*($max/$len);
    };
    
    echo sprintf("Max conformity is %s%%\n", number_format(conformity($arr1, $arr2), 2));
    Ответ написан
  • Ошибка include при отправки пути до файла через переменную, почему возникает и как решить?

    У APPDIR, возможно, слэш в конце есть? Из-за этого путь получается примерно таким: /var/www/site//views/contents/main.html

    Попробуйте убрать слэш в начале строки: /views/contents/main.htmlviews/contents/main.html
    Ответ написан
  • Зачем в PHP ссылки?

    Если что, «в методах объекта, $this всегда является ссылкой на вызывающий объект»

    Если вы можете обойтись без использования $this в коде, то, определённо, ссылки вам не принесут пользы. :)

    class MyModel {
        private $db;
    
        public function __construct($db) {
            $this->db = $db;
        }
    }


    В коде выше тоже используется механизм ссылок — $db, которая передаётся в конструктор и свойство «db» класса MyModel указывают на один и тот же экземпляр объекта после того, как отработал конструктор MyModel.

    как это может помочь в работе с БД или на примере контроллера/модели что нибудь повседневное такое для PHP программиста , было бы очень полезно для меня!!

    Я думаю, что механизм ссылок самым непосредственным образом помогает вам работать с БД. Но, так как ядро PHP само занимается оптимизациями, связанными со ссылками, от кодера не очень часто требуется их использовать явно.

    Это тоже самое, что жёсткие ссылки в файловой системе. От них может быть большая польза, но рядовой пользователь не очень часто их использует осознанно.
    Ответ написан
  • Что это за sublime?

    Это Seti UI.

    Оригинальная версия, если не ошибаюсь, работает только на версии 2. Есть порт для ST3, который требует ST3 Build 3062 и выше.
    Ответ написан
  • Заказчик вместо обещаных 3 часов моего времени делает правки уже 4й день, что делать?

    Возвращайте деньги, если он вам что-то платил, закрывайте проект и ставьте заказчику отрицательный отзыв. Это будет проще всего. Перед тем, как закрывать проект, озаботьтесь тем, чтобы из переписки на сайте биржи было понятно, что он требует что-то ещё дополнительное, но не хочет за это дополнительно платить. Если я не ошибаюсь, то закрытый проект, за который не уплачено ни цента, в вашей истории не появится. Во всяком случае, так обстоит дело на oDesk.

    Так же, на oDesk есть правило, по которому заказчик не может быть агентством, если он зарегистрировался как заказчик. Если он «проксирует» работу, то он — агенство, а агенство не может публиковать заказы. Он нарушает правила. Это ещё один момент, который вам может помочь, если вы вступите с клиентом в какой-то диспут. Опять же, важно, чтобы он упоминал в личной переписке на сайте биржи, что он, дескать, посредник, а не заказчик — если он этого не упоминал, то нужно его как-то на это развести.

    В остальном, я в похожих ситуациях обычно упираюсь и говорю, что никак не могу продолжать работу, пока не получу оплату за то, что было оговорено. Приплетаю всякие фантастические истории, что, как будто, меня недавно так кинули и я никому не могу доверять и т.д. и т.п. — тут всё ограничено фантазией. Главное: ни в коем случае не грубите человеку, на три буквы можно и вежливо посылать, закрутив всё ещё таким образом, что заказчик останется в восторге.

    Главное, и не только в подобных ситуациях, не тянуть резину. Чем вы будете мягче и податливее, чем дольше вы будете откладывать «неприятные» для клиента вопросы, тем чаще этим будут пользоваться окружающие, продавливая вас насколько это возможно. Это не значит, что нужно всем направо и налево грубить и посылать, это значит, что нужно сразу же сообщать окружающим, что вас что-то не устраивает — вежливо, но твёрдо.

    Я могу только посочувствовать вашей ситуации, но рано или поздно каждый человек с таким сталкивается. Со временем просто развивается чуйка, которая позволяет сразу видеть что конкретный проект публикует неадекватный клиент. Как говорил alexgilev (полчаса назад :) ), всякие фразы, вроде: «срочно», «мне мой знакомый программист сказал, что тут дел — на пять минут», «час-два для тех, кто в теме», «быстрые деньги» и т.п. — это один из признаков неадекватности.
    Ответ написан
  • Где лежит каркас страницы index на движке Opencart?

    Я сначала пытался объяснить, как устроен Opencart, чтобы вам было легко потом находить, какие шаблоны используются на конкретной странице, но получается, что это будет слишком объёмно. Поэтому я представлю ситуацию, когда используется стандартная установка Opencart.

    Заголовочная часть HTML-кода, шапка страницы, плюс выпадающее меню категорий, плюс уведомления — <корень сайта>/catalog/view/theme/<название шаблона>/template/common/header.tpl

    Футер — <корень сайта>/catalog/view/theme/<название шаблона>/template/common/footer.tpl

    Контент — зависит от текущего пути. Например, если текущий путь — product/product (страница товара), то шаблон можно найти в <корень сайта>/catalog/view/theme/<название шаблона>/template/product/product.tpl. Если корневая страница сайта (вы её назвали index), то её шаблон лежит в <корень сайта>/catalog/view/theme/<название шаблона>/template/common/home.tpl.

    Левая колонка — <корень сайта>/catalog/view/theme/<название шаблона>/template/common/column_left.tpl

    Правая колонка — <корень сайта>/catalog/view/theme/<название шаблона>/template/common/column_right.tpl

    Служебная часть перед контентом — <корень сайта>/catalog/view/theme/<название шаблона>/template/common/content_top.tpl

    Служебная часть после контента — <корень сайта>/catalog/view/theme/<название шаблона>/template/common/content_bottom.tpl

    <название шаблона> можно узнать на странице настройки магазина в админке: Админка → Меню «Система» → пункт «Настройки» → ссылка «Изменить» напротив текущей конфигурации → вкладка «Магазин» → пункт «Шаблон».

    Всё содержимое обычно компонуется из этих кусков.

    Правая и левая колонки, а так же служебные части перед и после контента обычно заполняются модулями — в зависимости от настроек модулей. Эти четыре шаблона лучше не трогать, если вы не уверены до конца, что делаете.
    Ответ написан
  • Почему try..catch не отлавливает ошибку?

    Проблема в том, что XMLHttpRequest выкидывает только два исключения:

    exception XMLHttpRequestException {
      unsigned short     code;
    };
    const unsigned short NETWORK_ERR = 101;
    const unsigned short ABORT_ERR = 102;


    NETWORK_ERR — ошибка сети.
    ABORT_ERR — пользователь отменил запрос.

    Ещё один немаловажный момент: NETWORK_ERR и ABORT_ERR не выкидываются в асинхронном режиме.

    Всё остальное отлавливаться не будет, и нужно писать свой обработчик, который, например, будет реагировать на код ответа 404 от сервера и т.д.

    function test(data) {
     // taking care of data
    }
    
    function handler() {
     if(this.readyState == 4 && this.status == 200) {
      // so far so good
      if(this.responseXML != null && this.responseXML.getElementById('test').firstChild.data)
         // success!
       test(this.responseXML.getElementById('test').firstChild.data);
      else
       test(null);
     } else if (this.readyState == 4 && this.status != 200) {
      // fetched the wrong page or network error...
      test(null);
     }
    }
    
    var client = new XMLHttpRequest();
    client.onreadystatechange = handler;
    client.open("GET", "test.xml");
    client.send();


    Здесь function handler() — обработчик, а client.onreadystatechange = handler; — привязка этого обработчика к экземпляру XMLHttpRequest.

    Просто ответ от сервера с кодом «404 Страница не найдена» не считается за NETWORK_ERR, потому что сервер ответил на запрос. А то, с каким он кодом ответил — это уже на другом уровне обрабатывается.
    Ответ написан
  • Как добавить комплектации товара с разными ценами?

    Это организовывается с помощью опций на странице редактирования товара. При добавлении опции можно указать сумму, которая прибавится/вычтется из стоимости при её выборе.

    Инструкция: Опции товара
    Ответ написан
  • Какой тут может быть *овнокод?

    public function getIndex()
    {
        $where = ['uid' => Sentry::getUser()->id];
        if (Input::has('status')) {
            $where['status'] = Input::get('status') ? 1 : 2;
        }
    
        $company_list = new CompanyList();
    
        return View::make('dashboard.account', ['title' => 'Мои компании'])->with([
            'company' => $company_list->get($where)->paginate(1)
        ]);
    }


    Переменные $title и $company вообще не нужны. Для того, чтобы один раз использовать какое-то значение, не нужно создавать отдельную переменную — проще сразу это значение вставить в нужном месте. Есть исключения, вроде ситуации, когда нужно что-то по ссылке передавать, но это точно не та ситуация.

    Выражение Input::get('status') ? 1 : 2 не нужно обрамлять скобками. Скобки нужны, чтобы справиться с приоритетом, а «=» и так имеет приоритет ниже, чем «?:», и вокруг скобок больше ничего нет из того, что могло бы исказить результат из-за приоритетов.

    Использование Input::get('status') ? 1 : 2 — вообще спорная вещь. Всё равно, что писать: true ? true : false. Лучше строить код так, чтобы GET-параметру «status» присваивалось нужное готовое значение и использовать его, а не лепить конструкции.

    if (Input::has('status')) {
        $where['status'] = Input::get('status');
    }
    Ответ написан
  • Почему не срабатывает:last-child?

    Так происходит потому, что :last-child — это последний элемент родительского контейнера. Совсем последний. После него не должно быть никаких элементов. Не получится использовать и :last-of-type, так как last-of-type подразумевает последний элемент по имени, а не по классу (и если после последнего div.blog-item будет хотя бы один div на этом же уровне иерархии, этот div.blog-item перестанет быть last-of-type).

    Вообще, я разделители меду элементами делал бы так:

    .blog-item + .blog-item {
        /* В ситуации с 5-ю элементами с классом .blog-item, которые строго 
         * следуют друг за другом, этот селектор применится
         * к элементам со второго по пятый. Первый будет проигнорирован.
         */
    }
    Ответ написан
  • Принцип работы буфферизированного вывода в php?

    Чтобы ничего не выводилось, нужно вызывать функцию ob_end_clean.

    Я обычно с буфером так работаю:

    ob_start();
    
    // Тут какой-нибудь вывод
    
    // В переменную $output заносится весь буфер, и её можно потом где-то использовать
    $output = ob_get_contents();
    
    // Очистка буфера
    ob_end_clean();


    Хотя, можно ещё проще делать: вместо связки ob_get_contents + ob_end_clean можно использовать ob_get_clean, которая очищает буфер и при этом возвращает его содержимое.

    ob_start();
    
    // Тут какой-нибудь вывод
    
    // В переменную $output заносится весь буфер, и её можно потом где-то использовать.
    // При этом происходит очистка буфера.
    $output = ob_get_clean();
    Ответ написан