Отправить один объект из модели методом в CakePHP

Я в основном форматирую URL-адреса перед отправкой своего объекта в представление для циклического прохождения (с foreach() на $submissions. У меня проблема в том, что parse_url() принимает один индекс, а не весь объект массива.

У меня есть этот метод в моем SubmissionsController:

public function newest() {        
    $submissions = $this->Submission->find('all', array(
        'conditions' => array('Submission.approved' => '1'),
        'order' => 'Submission.created DESC'
            ));

    $this->set('submissions', $submissions);
    $this->set('sourceShortUrl', AppController::shortSource($submissions));
}

В моем AppController у меня есть этот метод, который возвращает отформатированный URL-адрес:

protected function shortSource($source) {
    return $sourceShortUrl = str_ireplace('www.', '', parse_url($source, PHP_URL_HOST));
}

Это работает для отдельных записей, но parse_url не может принимать массивы, поэтому есть ли в контроллере способ отправить индекс объекта? Например. $submissions['Submission']['source'] до того, как я просмотрю его в представлении?

Моей альтернативой было сделать что-то подобное в моем методе shortSource($source):

if (is_array($source)) {
    for ($i = 0; $i < count($source); $i++) {
        return $sourceShortUrl = str_ireplace('www.', '', parse_url($source[$i]['Submission']['source'], PHP_URL_HOST));
    }
}

Но это просто возвращение первого (очевидно). Как лучше всего это сделать?


person bob_cobb    schedule 26.02.2012    source источник


Ответы (1)


Вы на правильном пути. Проверить наличие массива. Если это массив, вызывайте его рекурсивно для каждого элемента в массиве.

/**
* shortSource
*
* Returns an array of URLs with the www. removed from the front of the domain name.
* 
* @param mixed $source Either a string or array
* @return mixed $sourceShortUrl An array of URLs or a single string
*/
protected function shortSource($source) {
    if (is_array($source)) {
        foreach ($source as $url) {
            $sourceShortUrl[] = $this->shortSource($url);
        }
    } else {
        $sourceShortUrl = str_ireplace('www.', '', parse_url($source, PHP_URL_HOST));
    }
    return $sourceShortUrl;
}

В этой рекурсивной функции она будет анализировать одну строку или массив строк.

// in the view
if (is_array($sourceShortUrl)) {
    foreach ($sourceShortUrl as $url) {
        // view specific code for URL here
    }
}
person Chuck Burgess    schedule 26.02.2012
comment
Красиво спасибо чувак! В итоге я немного изменился, и теперь я просто вызываю его в представлении как SubmissionsController::shortSource($submission['Submission']['source']), поэтому ему не нужно быть в AppController и быть защищенным. - person bob_cobb; 26.02.2012
comment
@bob: хотя в первую очередь его не должно быть в контроллере. мне кажется больше похожей на библиотечную функцию... - person mark; 26.02.2012
comment
Зависит от архитектуры. Если его нужно использовать в нескольких местах, то да. Или, если он используется во всех полях URL-адреса, это будет даже лучше в качестве поведения. Но если это относится только к URL-адресам в этом контроллере, лучше оставить его в контроллере/модели здесь, чтобы код был лучше организован. - person Chuck Burgess; 27.02.2012