Как преобразовать существующий файл библиотеки PHP, чтобы его можно было использовать в рамках CakePHP? - PullRequest
0 голосов
/ 22 января 2011

У меня есть эта библиотека в формате PHP без Cake, обычный сценарий PHP, который в настоящее время работает как шарм. Мне нужно использовать это в рамках Cake. Файл библиотеки выглядит следующим образом: (пример извлечен)

<?php

// REST API functions

function sendAction($itemurl, $itemimageurl, $sessionid, $userid, $rating=""){

    global $someapiwebsiteURL, $apiKey, $tenantId;
    $somewebsiteAPI = $someapiwebsiteURL.$action."?apikey=".$apiKey.
                                                                 .....
                ................
    }


    //Codes extract


?>

Я сталкивался с несколькими способами сделать это. В настоящее время в замешательстве, как я собираюсь поместить этот файл библиотеки в мою платформу Cake?

  1. App :: импорт ()
  2. Datasource

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

В настоящее время работает в структуре фреймворка, отличного от Cake, страница просмотра выглядит следующим образом: (пример извлечен)

<?php
// my view page

$viewResponse = sendAction($itemdescription ,$itemurl , $itemimageurl,$sessionid,$userid);

//sample code only
?>

Оба файла работают нормально. Логика помещения его в структуру CakePHP - вот проблема. Кто-нибудь может предложить «способ» сделать это без чрезмерной работы с источником данных? Если нам нужно использовать источник данных в App / models / datasources /, то какова его структура? Как, например, в файле источника данных, мы включаем функции библиотеки? или это какой-то общий источник данных ReST, который можно найти здесь: CakePHP ReST источник данных . Я просмотрел главу поваренной книги, посвященную источнику данных, и понимаю, что мы должны определить источник данных в нашем database.php, но если кто-то уверен в своем способе выполнить его, используя метод datasource или app :: import (), пожалуйста, поделитесь с подробнее?

UPDATE:

Привет, Лайонел! Спасибо, что наполнился. Ну, на самом деле пользователи нажимают на действие вида: function view () {} в моем foods_controller Я добавляю некоторые скрипты сюда, чтобы включить мою функцию просмотра в мой foods_controller, так что, возможно, это поможет вам легче помочь. Спасибо ..

function view($id = null) {
        if (!$id) {
            $this->Session->setFlash(__('Invalid food', true));
            $this->redirect(array('action' => 'index'));
        }
        $this->set('food', $this->Food->read(null, $id));       
    }
  • Действие просмотра запускает функцию send_action (каждый раз, когда пользователь нажимает на страницу просмотра на контроллере продуктов). Поэтому каждый раз, когда пользователь нажимает на действие просмотра, его (динамические переменные): userid, sessionid, itemid этой страницы, url, itemdescription; (значение timerange является статическим строковым значением «ALL»), и, если оно есть (и т. д.), пока доступны только эти значения: Будет использоваться в качестве «параметров» в функции «Отправить действие». То, что вы написали, близко к тому, что могут делать коды. Ты прав. Кроме того, что мы должны включить функцию Send Action внутри view () в контроллере пищевых продуктов?

  • Если мы посмотрим на динамическое заполнение переменных, упомянутых в пункте выше, не могли бы вы изменить свой второй код (например, код из вашего product_controller, например), чтобы он также работал для динамического получения переменных? (как вы спрашивали в последнем обновлении: как получить параметры ..)

  • Просто чтобы было понятно.

    1. Пользователь просматривает страницу. Действие отправки собирает данные и отправляет их в API. (как мы уже сделали, вызвав функцию в библиотеке (ACME.php). * просто ожидая вашего обновления, если это возможно, спасибо.
    2. В представлении функций () контроллера пищевых продуктов: есть также дополнительный вызов. Второе призвание (2):

$recommendResponse = getRecommendations("otherusersviewed", $itemId, $userId);

Второй вызов вызывает библиотечный файл ACME.php, в котором содержится (2) вторая функция, которая извлекает данные, вот она: (она в рабочем состоянии, но ее просто нужно преобразовать в публичную статическую функцию, подобную вам сделал для (1) первой функции. Не могли бы вы также помочь изменить этот код?:

function getRecommendations($recommendationType, $itemId, $userId){

    // sample code similar to the first one.
}

Вот и все. В обычном формате PHP это кажется довольно простым, и он работает легко, но для некоторых это очень сложно для меня. Спасибо за помощь, Лайонел. :-)

P.S. Привет, Лайонел, я заметил, что что-то пропало в библиотеке после изменений? Посмотрите изначально у нас есть это:

$somewebsiteAPI = $someapiwebsiteURL.$action."?apikey=".$apiKey.

Смотри, переменные для $SomeWebsiteAPI и $SomeApiWebsiteURL разные. Я что-то упустил? или ты модифицировал так, чтобы он был эффективнее? Я вижу, что переменная с именем $SomeWebsiteAPI изменена, чтобы стать переменной с именем $link? и переменная $SomeApiWebsiteURL заменяется на именованную переменную $url, я прав? .. Спасибо.

Спасибо, с наилучшими пожеланиями. Джон Максим

1 Ответ

3 голосов
/ 22 января 2011

Для меня, если у меня есть этот кусок кода, я сначала обернул бы его в статический (или нормальный) класс и назвал бы его ACME, а затем переместил бы acme.php в /apps/libs/acme.php. Тогда в контроллере я буду использовать App::import('Lib', 'acme'). Это действие делает только запрос файла, поэтому вы можете просто использовать его мгновенно, позвонив по номеру ACME::sendAction(...).

.

А что касается global, вам может потребоваться просто объявить статический (или нормальный) класс, а затем определить общие переменные как часть свойств класса, чтобы вы могли делиться ими со всеми функциями в классе.

Например, это /app/libs/acme.php

class ACME {

    private static $someapiwebsiteURL = "http://thewebsite/api/1.0/"; 
    private static $apiKey = "0010KIUMLA0PLQA665JJ";   
    private static $tenantId = "THE_TENANT_NAME";

    /**
     * Simple builder to build links from array of $params
     *
     * @param string $url The api url
     * @param array $params The given parameters
     * @return string built url
     */
    private static function BuildLink($url="", $params=array()) {

        $link = $url;
        foreach($params as $k=>$v) {
            $link .= "&$k=$v";
        }

        //Replace the first & to ?
        $link = preg_replace("/&/", "?", $link, 1);

        //Not sure if we need URL encode here, please uncomment this
        //if the API could not work.
        //$link = urlencode($link);

        return $link;
    }

    public static function SendAction($action, $itemId, $itemdescription, $itemurl, $itemimageurl, $sessionid, $userid, $rating="") {

        $somewebsiteAPI = self::BuildLink(self::$someapiwebsiteURL.$action, array(
            "apikey"=>self::$apiKey,
            "sessionid"=>$sessionid,
            "userid"=>$userid,
            "tenantid"=>self::$tenantId,
            "itemid"=>$itemId,
            "itemdescription"=>$itemdescription,
            "itemurl"=>$itemurl,
            "itemimageurl"=>$itemimageurl,

            /**
             * Assuming your API smart enough to only use this value when
             * the action is "rate"
             */
            "ratingvalue"=>$rating 
        ));

        $xml = simplexml_load_file($somewebsiteAPI);
        return $xml;
    }

    public static function GetRecommendations($recommendationType, $itemId, $userId) {
        $somewebsiteAPI = self::BuildLink(self::$someapiwebsiteURL.$recommendationType, array(
            'apikey'=>self::$apiKey,
            'tenantid'=>self::$tenantId,
            'itemid'=>$itemId,
            'userid'=>$userId
        ));

        $xml = simplexml_load_file($somewebsiteAPI);
        return $xml;
    }
}

А в вашем контроллере

App::import('Lib', 'acme');

class FoodController extends AppController {

    //Food is plural already I assume? You can just use
    //food, should be ok I think, else it will be weird
    //to use /foods/view/?
    var $name = "Food";
    var $uses = array("Item", "Food");

    function view($id="") {
        //We accepts only valid $id and $id > 0.
        //Take notes that this $id will be a string, not int.
        if (ctype_digit($id) && $id > 0) {


            //I don't know how you would gather the information, but I assume you
            //have a database with the information ready.

            //I assumed you have an `items` table
            $item = $this->Item->findById($id);

            $sessionid = "00988PPLO899223NHQQFA069F5434DB7EC2E34"; //$this->Session->...?
            $timeRange = "ALL";
            $userid = "24EH1725550099LLAOP3"; //$this->Auth->user('id')?

            if (!empty($item)) {
                $desc = $item['Item']['description'];
                $url = "/foods/view/".$id;
                $img = $item['Item']['img'];

                $viewResponse = ACME::SendAction("view", $id, $desc ,$url, $img, $sessionid, $userid);
                $this->set('food', $this->Food->read(null, $id));
            }else{
                $this->Session->setFlash(__('Invalid food', true));
                $this->redirect(array('action' => 'index'));
            }    
        }else{
            $this->Session->setFlash(__('Invalid food', true));
            $this->redirect(array('action' => 'index'));    
        }

    }

}

Редактировать

Код был заполнен и, конечно, без каких-либо гарантий :). Лично мне не очень нравится иметь длинные аргументы в функции (например, SendAction, обрезка ошибок), я использую более короткий аргумент, такой как $params в ACME::BuildLink. Но просто для того, чтобы уважать ваш код, я не особо изменил метод SendAction.

Тогда я не слишком уверен, как бы вы использовали этот код, поэтому я предположил, что у вас есть ProductsController и каким-то образом URL-адрес пользовательского триггера, например /products/send_action/. Если вы сможете предоставить больше информации, мы сможем помочь.

Редактировать снова

Я изменил класс ACME, а также контроллер. Да, я пропускаю некоторые переменные, но я добавил их обратно в обновленный код.

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

А для личных соглашений я обычно использую статические методы, например ACME:GetRecommendations или ACME::SendAction.

.

О да, я лучше вернусь к переменным, которые вы использовали. Извините за их изменение, просто мне не нравятся длинные имена:)

И, кстати, корпорация RoadRunner ACME Corporation ? Лол!

Приветствие Лайонел

...