CakePHP, организовать структуру сайта вокруг групп - PullRequest
0 голосов
/ 19 августа 2010

Итак, я не совсем уверен, как мне следует структурировать это в CakePHP для правильной работы в правильной форме MVC.

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

  • Команда
  • Задача
  • Снаряжение

Это, как правило, сайты, которые довольно легко структурировать и создавать.в торт.Например, у меня есть модель, контроллер и вид для каждого набора элементов.

Моя проблема (и я уверен, что многие другие уже имели и уже решили ее) состоит в том, что у меня уровень вышенаборы предметов.Так, например:

  • Отдел
    • Команда
    • Задача
    • Снаряжение
  • Отдел
    • Команда
    • Задача
    • Снаряжение
  • Отдел
    • Команда
    • Задача
    • Оборудование

На моем сайте мне нужно, чтобы кто-то мог просматривать сайт на уровне отдельной группы, а также перемещаться, чтобы просматривать все это вместе (т. Е.игнорировать группы).

Итак, у меня есть модели, представления и элементы управления для Отдела, Группы, Задачи и Оборудования.

Как мне структурировать свой сайт так, чтобы из представления Департаментакто-то может выбрать отдел, а затем перемещаться по сайту, чтобы перейти к различным представлениям для команды / задачи / оборудования, показывая только те, которые принадлежат этому конкретному отделу.

В этом же формате естьспособ также перемещаться, игнорируя ассоциации отдела?

Надеемся, что URL-адреса следующих примеров прояснят что-нибудьг, что было неясно:

// View items while disregarding which group-set record they belong to
http://www.example.com/Team/action/id
http://www.example.com/Task/action/id
http://www.example.com/Equipment/action/id

http://www.example.com/Departments

// View items as if only those associated with the selected group-set record exist
http://www.example.com/Department/HR/Team/action/id
http://www.example.com/Department/HR/Task/action/id
http://www.example.com/Department/HR/Equipment/action/id

Можно ли заставить контроллеры функционировать таким образом?Есть ли кто-нибудь, чтобы прочитать, чтобы я мог понять это?

Спасибо тем, кто все это читает:)

Ответы [ 3 ]

1 голос
/ 20 августа 2010

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

http://example.com/team/group:hr http://example.com/team/action/group:hr/other:var

Это может также потребовать пользовательских маршрутов ... но это должно сделать работу.

http://book.cakephp.org/view/541/Named-parameters http://book.cakephp.org/view/542/Defining-Routes

1 голос
/ 06 сентября 2010

Мне кажется, я знаю, что ты пытаешься сделать. Поправь меня, если я ошибаюсь:

Я создал менеджер проектов для себя, в котором я хотел, чтобы URL были более логичными, поэтому вместо использования чего-то вроде

http://domain.com/project/milestones/add/MyProjectName Я мог бы использовать http://domain.com/project/MyProjectName/milestones/add

Я добавил пользовательский маршрут в конец (! Важный) моих маршрутов, чтобы он перехватывал все, что не является маршрутом, и рассматривал его как «переменный маршрут».

Router::connect('/project/:project/:controller/:action/*', array(), array('project' => '[a-zA-Z0-9\-]+'));

Какой бы путь вы ни выбрали, это означает, что вы уже (или никогда) не можете иметь контроллер с таким именем, поэтому я считаю хорошей практикой использовать единственное слово вместо множественного числа. (У меня есть Projects Controller, поэтому я использую «project», чтобы избежать конфликта с ним.)

Теперь, чтобы получить доступ к параметру: project в любом месте моего приложения, я использую эту функцию в моем AppController:

function __currentProject(){
// Finding the current Project's Info
    if(isset($this->params['project'])){
        App::import('Model', 'Project');
        $projectNames = new Project;
        $projectNames->contain();
        $projectInfo = $projectNames->find('first', array('conditions' => array('Project.slug' => $this->params['project'])));
        $project_id = $projectInfo['Project']['id'];
        $this->set('project_name_for_layout', $projectInfo['Project']['name']);
        return $project_id;
    }
}

И я использую его в других моих контроллерах:

function overview(){
    $this->layout = 'project';

    // Getting currentProject id from App Controller
    $project_id = parent::__currentProject();

    // Finding out what time it is and performing queries based on time.
    $nowStamp = time();

    $nowDate = date('Y-m-d H:i:s' , $nowStamp);
    $twoWeeksFromNow = $nowDate + 1209600;

    $lateMilestones = $this->Project->Milestone->find('all', array('conditions'=>array('Milestone.project_id' => $project_id, 'Milestone.complete'=> 0, 'Milestone.duedate <'=> $nowDate)));
    $this->set(compact('lateMilestones'));

    $currentProject = $this->Project->find('all', array('conditions'=>array('Project.slug' => $this->params['project'])));
    $this->set(compact('currentProject'));
}

Для вашего проекта вы можете попробовать использовать маршрут, подобный этому, в конце вашего файла rout.php:

Router::connect('/:groupname/:controller/:action/*', array(), array('groupname' => '[a-zA-Z0-9\-]+'));

// Обратите внимание, что я удалил "/ project" с самого начала. Если вы сначала поставите: groupname, как я делал в последнем примере, у вас будет только одна опция для этих пользовательских URL-маршрутов.

Затем измените другой код в соответствии с вашими потребностями.

1 голос
/ 20 августа 2010

СЕССИИ

Поскольку сеть не имеет состояния, вам необходимо использовать сеансы (или файлы cookie). Вопрос, который вам нужно будет задать себе, заключается в том, как отразить выбор (или нет) конкретного отдела. Это может быть так же просто, как поместить раскрывающийся список в верхнем правом углу, который отражает ВСЕ, HR, Продажи и т. Д. Когда раскрывающийся список изменится, он установит (или очистит) переменную сеанса группы.

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

// for all functionality use:
http://www.example.com/Team/action/id
http://www.example.com/Task/action/id
http://www.example.com/Equipment/action/id

Вы не меняете URL, чтобы приспособиться к функциональности. Это похоже на использование другого URL-адреса для каждого ПОЛЬЗОВАТЕЛЯ, желающего увидеть свой АДРЕС, ТЕЛЕФОН или ИНФОРМАЦИЮ О СЧЕТЕ. Где USER - это группа, а АДРЕС, PHONE NUMBER <и BILLING INFO - наборы элементов. </p>

БЕЗ СЕССИЙ

Другой вариант - установить фильтр групп на каждой странице. Так, например, в представлении «Команда / индекс» у вас будет выпадающий список для фильтрации данных. Это позволит выполнить то же самое без необходимости устанавливать и очищать переменные сеанса.

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

Имеет ли это смысл?

...