• Как организовать взаимодействие админ. панели и остальных модулей?

    @romeo7
    Структура Вашего приложения:
    58d11ec2ff8247e28f9e7f65f9ca95fb.png
    В index.php (условный bootstrap Вашего приложения) осуществляем роутинг.
    pastebin.com/gcFPbtP8
    Если в роутинге реализованы группы (в ZF это child_routes), то /admin/ можно вынести в отдельную группу:
    pastebin.com/PBL6bTHt
    В папке models хранятся модели. Модель Velo возвращает данные, к примеру, из БД.
    Actions находящиеся в контроллере VeloController делегируют данные во вьюху (actionIndex) или, как в случаи, actionCreate, actionUpdate и actionDelete - осуществляется необходимые действия и производят редирект.
    pastebin.com/kMNCHV4f
    Прошу заметить, что контроллер бэкенда (админки) наследуется от контроллера фронтенда:
    class VeloController extends \apps\frontend\controllers\VeloController

    Вполне возможно, что, к примеру, добавление Velo доступно не только администрации сайта, но и обычному смертному. С Velo не очень удачный пример, лучше Comments. Аналогично и с моделями.
    Только помните, что использование жирных, уродливых actions не является хорошей практикой. Фильтрацию (санитизацию) и валидацию данных request можно осуществить в модели. Пример с rules, если помните.

    P.S. Заметил, что у Вас множество вопросов в toster связано с ZF2. Сложности возникают потому, что у ZF чуть более высокий порог входа. Для начала лучшим выбором мог быть любой микрофреймворк (Laravel, CodeIgniter,...)

    UPDATE

    > А почему у вас фигурирует 2 модели?
    Логично предположить, что запрос к БД на возврат списка велосипедом может фигурировать, как в админке, так и для вывода, к примеру, на главной странице. Удаление, добавление, обновление записи может быть доступно только через админку. Потому:
    namespace apps\frontend\models;
    
    class Velo extends ActiveRecord
    {
       public static function tableName()
       {
           return 'tbl_velo';
       }
       public function getAll($limit)
       {
          return static::find()->limit($limit)->asArray()->all();
       }
    }

    Модель для админки:

    namespace apps\backend\models;
    
    class Velo extends \apps\frontend\models\Velo
    {
       public static function create($content)
       {
            $velo = new static;
            $velo->content = $content;
            return $velo->save();
       }
    
       public static function update($id, $content)
       {
           $conditions = ['id' => $id];
           return static::updateAll(['content' => $content], $conditions);
       }
    
       public static function delete($id)
       {
           return static::deleteAll(['id' => $id]);
       }
    }


    Я зря написал запросы на добавление/обновление/удаление/ в контроллере.
    Данная модель характерна для Yii2, которая строится на ORM ActiveRecord (паттерн).
    В Doctrine используется немного иной паттерн - Data mapper.
    Для каждой модели есть свой контроллер, ибо на главной и админке список может выглядеть иначе - разные вьюхи. А, к примеру, для ajax-а (помимо frontend, backend, добавится директория ajax. Для условности назовём всё это scopes) данные будут возвращаться в JSON, т.е. без вьюхи.
    Контроллер Velo для frontend:
    pastebin.com/diXPu5yY
    Контроллер Velo для backend:
    pastebin.com/3s7EpJAD
    Вот и вся MVC ;)
    Ответ написан
    8 комментариев
  • Стоит ли писать свой php-фреймворк с целью улучшения знаний в области ООП и изучения шаблона MVC?

    @romeo7
    Читая Ваш вопрос,вспомнил себя 5-ей летней давности:) На тот момент мой бэкграунд состоял из дюжины сайтов на различных CMS и одного стартапа,который ясное дело не взлетел. Я к тому моменту долго вынашивал план по реабилитации одного замороженного проекта (спортивный портал),который разрабатывал со своими товарищами ещё в студенческие годы. Изначально задачи написать свой движок не было,но... всё началось с разработки шаблонизатора с синтаксисом а-ля CMS MODx. Много читал о том,что данная реализация выделяется на фоне остальных конкурентов,по сути являясь визитной карточкой последней. На поверку оказалось, что это всего навсего синтаксическая абстракция над Smarty,со всеми вытекающими по производительности. К примеру,моя реализация имеет альтернативную поддержку нативного php-шаблонизатора
    <?=$this->getSnippet('List', $params)?>
    для тех, кто терпеть не может синтаксические абстракции (Smarty, Twing, Fenom и иже с ними.) из-за их низкой производительности и иным религиозным соображениям.
    Шло время, кодовая база росла. От паттерна Singleton до DI (Dependency Injection), к Service Locator-у. Много чего выпилено в угоду существующих решений. За последние 2 года,не без помощи Composer,стало в разы больше готовых решений,причём несколько на реализацию конкретно задачи. К примеру,из последнего - был заменён собственный файловый менеджер (манипуляция с файловой системой) на библиотеку Flysystem, ибо последняя помимо всего прочего, умеет "бегать" в облака. Круто же ;) Единственное,в моей реализации была возможность поиска по regexp-паттерну,пришлось писать абстракцию.

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

    Вот сходу антипример. Достаточно популярная библиотека для валидации данных Respect Validation. Требовалось реализовать интернационализацию сообщений, не было возможности вывести иерархию выброшенных во время валидации ошибок одним большим массивом,а также хотелось вернуть,к примеру,только первую ошибку (first) или последнюю (last). Пришлось форкнуть,ибо абстрагироваться попросту невозможно.

    Совет: Иногда сталкиваешься с тем, что не все возможности какой-либо библиотеки задокументированы,даже если она достаточно популярна и имеет свой красивый "твиттеробутстраповый" сайт. Загляните в unit-тесты,возможно,откроете для себя что-то новое;)

    Если всё же надумаете писать свой фреймворк,то опирайтесь на существующие решения. Выберите для себя один-два популярных фреймворка и изучите,как реализован в них тот или иной функционал,хотя бы визуально,благо документации навалом. Начните с модели MVC. Посмотрите как реализованы actions,а именно доступ к ним,фильтрация на входе и выходе в action. Я,к примеру,не сторонник реализации псевдо-аннотаций,как в Symfony,ибо в PHP поддержки нативных аннотаций пока нет,а всё остальное - это жалкое подобие через медленные Reflections,даже если всё это кэшируется. Вот и автор АОП парадигмы для PHP всё это понимает, но всё равно продолжает разрабатывать свой проект Go!. Реализация конечно интересная,но я обойдусь событийной моделью (Observer или PubSub).
    Взгляните как устроен роутинг, ибо это основополагающая для реализации SOAP и REST. К примеру,моё решение испытало влияние Lavarel Routing по части использования групп. Нынче в силу распространённости мобильных платформ всё чаще используется REST не только на основе url-а,но и на основе кастомных заголовков (X-<имя прагмы>).
    Обратите внимания на то,как осуществляется обработка ошибок/exceptions. К примеру,Yii давно ругают на то,что нет возможности верной идентификации того или иного исключения. Лучше для каждой отдельной задачи (к примеру, FileManager) свой класс Exception,который наследуется от базового:
    class Exception extends BaseException
    {
        const FILE_EXISTS = 'File exists: {path}';
    
        public function __construct(
            $level = self::ERROR,
            $msg = null,
            array $dataReplace = null,
            \Exception $handler = null
        ) {
            return parent::__construct($level, $msg, $dataReplace, $handler);
        }
    }

    Тогда в базовом классе BaseException можно легко реализовать логирование (к примеру, воспользоваться Monolog) и красивую визуальную выдачу в режиме дебага (к примеру, Whoops).
    Желательно сразу избавить себя от привычки делать "жирные" контроллеры/actions. В этом может Вам помочь различные реализации валидации,фильтрации данных,а также задания дефолтовых значение на уровне модели. Обратите внимание на метод rules. Тогда в Вашем контроллере будет лишь метод отправки уже обработанных данных на вьюху.
    Что касается ORM и DBAL (синонимы: DAO и Query Builder), то в этом случае уж точно не стоит изобретать свой "велосипед". Написать по возможности единый интерфейс для различных реляционных и нереляционных решений (СУБД, Систем полнотекстового поиска/индексаторов (Sphinx, Elasticsearch)) - более чем нетривиальная задача. Я в своём фреймворке взял за основу AR (ORM) и Query Builder Yii2. Да,в Yii отсутствует модульность,а потому всё достаточно зависимо друг от друга,но если захотеть, то можно.
    Чувствуете этот момент. Вы препарируете почти готовое (прим. Yii2 еще в состоянии беты),одно из самых выдающихся на текущий момент решений и тем самым разбираетесь во всех тонкостях, попутно проявляете активность в исправлении ошибок.
    Научитесь писать unit тесты. Множество ошибок всплывут на поверхности,да и сон Ваш тогда будет более крепким.
    Вы наверно могли для себя заметить на том же stackoverflow или иных ресурсах, задаются достаточно тривиальные вопросы по фреймворкам. Вот и сейчас пока пишу Вам этот большущий ответ,в разделе "Похожие вопросы" красуется такой вопрос "Как реализовать правильно авторизацию с сессиями ... Отсутствует элементарная дисциплина к самостоятельности. И я даже догадываюсь почему так. Фреймворков стало больше,фреймворки стали лучше. Programmer Frendly,а не страшный зверь для избранных,как было когда-то. Правда,некоторые и по сей день недружелюбно скалятся;) Так или иначе,если есть желание задать вопрос из серии каким образом в JQuery сравнить две переменные,то стоит задуматься,а надо ли тебе всё это.
    Не в коем случае не нужно уверять себя в том,что Ваш инструмент взлетит. Он не уникален,и в конечном счёте скорее всего будет состоять из множества готовых библиотек (прим. в моём случае 60 против 40% вендорного кода. Если учитывать значимость,то в этом случае, уже счёт будет не в мою пользу). К сожалению, не могу найти ссылку на англоязычную статью, где автор сетует на полный отказ от фреймворков в пользу packagist. Даже если в уникальности вашего решения нет сомнения,это ничего Вам не гарантирует. Необходимо грамотное продвижение - множество статей на тематические ресурсах,а также участие в конференциях. К примеру, PHPDaemon хоть и стартовал первым, но пока вчистую проигрывает ReactPHP, а всего-навсего необходимо было уделить внимание написанию документации. Автор PHPDaemon, Василий Зорин,как-то на вопрос чем отчается его проект от React,указал на то,что последний использует его идеи. Конечно печально за нашего соотечественника,но его проект попахивает откровенным эгоизмом.
    Делайте Ваш инструмент прежде всего для себя,и возможно,когда-нибудь он станет интересен кому-то ещё. Так или иначе,Вы получите бесценный опыт. Главное,постараться довести это дело до конца. Отличительной чертой нашей ремесленной профессии является терпение. Вот Вам и проверка этого замечательного человеческого качества:) Кстати,чтобы интерес не угас,стоит свои наработки применять,если не в продакшене,то хотя бы небольшой проект для экспериментов.
    Заметил за собой,что пока занимался разработкой инструмента,гораздо больше получил опыта,чем на предыдущих двух работах. Но это субъективно. Можно с самого начала устроится в такое место,где замечательный отзывчивый коллектив и не менее интересные проекты/стартап, а не "натяни шаблон на Wordpress". Считаю,что пусть CMS-сника - это путь в никуда, и Кипелов здесь не причём:) Чем раньше, тем раньше;)
    Мне, как и sWinDos тоже забавно смотреть на свои исходники годичной давности:)) Вам знакомо такое понятие,как "Тезаурус"? В трактовке теории информации,это экспоненциальный рост знаний/опыта до какого-то предела, после которого, эффективность полученных знаний/опыта заметно падает. Получается этакая кривая Гаусса или что-то вроде жизненного цикла знаний/опыта в отдельно взятой предметной области.

    Совет: Запомните,Ваши проекты на github-е и контрибьюторская активность - это твёрдое, незыблемое портфолио. На собеседовании в большинстве компаний вы вправе выбрать свой сценарий поведения и темы для бесед.

    P.S. Я специально не стал затрагивать моральную и финансовую сторону вопроса. Opensource или заработок? Вечные поиски свободного времени между семьёй,работой и отдыхом. Смотрю здесь уже кто-то отметился:) Если Вы ещё студент и не обременены чем-либо,то дерзайте. Вполне возможно уже по окончанию университета или даже раньше, Вы выйдите уверенным таким коренастым мидлом:) К слову,в первой организации, с которой я начал свой профессиональный путь проповедовали процедурное программирование,ибо ООП никем не понималось должным образом.
    Ответ написан
    6 комментариев
  • Почему моя функция линейного поиска в javaScript работает не правильно?

    @Yago
    вы прерываете цикл поиска через break - у вас получается одна итерация, вместо полного обхода массива

    var search = function(lastName){
        for(i=0;i<contacts.length;i++){
            if (lastName === contacts[i].lastName){
               printPerson(contacts[i]);
               return true;           
            } 
        }
       console.log("no matches");
       return false;
    };
    Ответ написан
    Комментировать
  • Как работать с Doctrine ObjectManager так же, как и с SQL запросом с JOIN? ZF2?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Да почитайте вы уже доментацию по Zend2/Doctrine! Честное слово, уже даже как-то не интересно.

    Читать про DQL или QueryBuilder.
    Ответ написан
    2 комментария
  • Как спроектировать модуль отдел, в котором были бы сотрудники отдела + краткое описание отдела под ZF2?

    По-моему писать два модуля для такой тривиально задаче сродни написания нового модуля для каждой новой веб страницы. Я написал такую штуку (правда лет 5 назад, еще на ZF 1.*), ничего необычного там нет, я бы порекомендовал вам лучше подумать над архитектурой БД.
    Ответ написан
    Комментировать
  • Как правильно составить AJAX запрос с serialize?

    @Yago
    Попробуйте вместо attr использовать prop:

    $(".sended-param").click(function(){
    	$(".sended-param").find("input[type=radio]").prop('checked', false);
    	$(this).find("input[type=radio]").prop('checked', true);
    	$.ajax({
    		type: "post",
    		url: "/filter",
    		data: $(".filter form").serialize(),
    		success: function(data) {
                console.log("Hello world!");
            }
    	});
    });
    Ответ написан
    1 комментарий
  • Почему возникает ошибка [PDOException] Could not find driver? ZF2/DoctrineORM?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Скорее всего вы для cli окружения не подключили модуль (хотя это странно), для него свой php.ini. Проверьте на всякий случай.
    Ответ написан
    6 комментариев
  • Как обновлять CMS с github?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    сделайте форк проекта cms, вносите туда свои правки и периодически мерджитесь с мастером.
    Если же изменения полезны - выносите в ишусы для обсуждения и предлагайте пул реквесты.
    Ответ написан
    3 комментария
  • Как организовать модуль так, чтобы его можно было удобно администрировать?

    viktorvsk
    @viktorvsk
    Ну вообще, то, что вы описываете, похоже на partial шаблонизатора
    С php знаком слабо. В Rails все понятно.
    В php простейшие "партиалы" у меня получались так:
    class View{
    public function render($template, $locals=array()){
    ob_start();
    extract($locals);
    $View = new View();
    include("/path/to/partials/${template}.php");
    return ob_get_clean();
    }
    }

    fullAction:
    echo $View->render('news', array('action'=>'edit));


    Можно рендерить партиал в партиале.
    Только замечу, что решение ужасное, т.к. не особо в теме. Но вот в Rails эти вещи решают хелперы form builder и шаблонизаторы. Думаю, в любом php фреймворке есть что-то аналогичное
    Ответ написан
    1 комментарий
  • Как спроектировать модуль отдел, в котором были бы сотрудники отдела + краткое описание отдела под ZF2?

    @m-haritonov
    Мне видятся следующие варианты:
    1. Написать приложение в виде одного модуля.
    2. Написать приложение в виде двух модулей, каждый из которых требует обязательного наличия другого модуля.
    3. Написать приложение в виде двух модулей, каждый из которых может работать как самостоятельно, так и в связке с другим модулем (если таковой установлен в систему).

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

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

    Третий вариант, соответственно, увеличит затраты на разработку из-за написания дополнительного кода (надо будет писать код как для ситуации, когда один модуль работает в паре с другим, так и для ситуации, когда один модуль работает изолированно от другого).

    Вообще, если из условия задачи исходит, что эти два модуля будут работать в паре и только в паре (т.е. изначально полная изолированность не закладывается), то разделять подобное приложение на модули, на мой взгляд, смысла нет.
    Ответ написан
    1 комментарий
  • Какую IDE использовать для разработки на C++?

    @FoxInSox
    Поделюсь с вами сокровенной тайной как найти ответ на 99% вопросов: вводите в Гугле ключевые слова вопроса, т.е. в вашем случае это "С++ OSX IDE" и вуаля ответ найден:

    stackoverflow.com/questions/2805895/c-ide-for-osx
    stackoverflow.com/questions/220644/c-ide-for-macs?lq=1
    Ответ написан
    Комментировать
  • Какую CMS выбрать для сайтов любого типа?

    drupal
    Ответ написан
    Комментировать