1

Symfony2 アプリケーション用のコンソール コマンドを作成する必要があり、こちらこちらのドキュメントを読みましたが、どれに従うべきかわかりません。これが私がしたことです。

  • の下にファイルを作成します。/src/PDI/PDOneBundle/Console/PDOneSyncCommand.php
  • 次のコードを記述します。

    namespace PDI\PDOneBundle\Console\Command;
    
    use Symfony\Component\Console\Command\Command;
    use Symfony\Component\Console\Input\InputArgument;
    use Symfony\Component\Console\Input\InputInterface;
    use Symfony\Component\Console\Input\InputOption;
    use Symfony\Component\Console\Output\OutputInterface;
    
    class PDOneSyncCommand extends Command
    {
        protected function configure()
        {
            $this
                ->setName('pdone:veeva:sync')
                ->setDescription('Some description');
        }
    
        protected function execute(InputInterface $input, OutputInterface $output)
        {
            $name = $input->getArgument('name');
            if ($name) {
                $text = 'Hello '.$name;
            } else {
                $text = 'Hello';
            }
    
            if ($input->getOption('yell')) {
                $text = strtoupper($text);
            }
    
            $output->writeln($text);
        }
    }
    
    • の下にファイルを作成します。/bin
    • 次のコードを記述します。

      ! /usr/bin/env php

      require __ DIR __ .'/vendor/autoload.php';

      PDI\PDOneBundle\Console\Command\PDOneSyncCommand を使用します。Symfony\Component\Console\Application を使用します。

      $application = 新しいアプリケーション(); $application->add(新しい PDOneSyncCommand()); $application->run();

しかし、実行php app/console --shellしてヒットしてコンソールに移動するとENTER、登録されたコマンドが表示されません。何が欠けていますか?

注: 私よりも経験豊富な人が、2 番目のコードを適切にフォーマットできますか?

更新 1

わかりました、提案に従って、回答を出発点として、このコードを作成しました:

protected function execute(InputInterface $input, OutputInterface $output)
{
    $container = $this->getContainer();

    $auth_url = $container->get('login_uri')."/services/oauth2/authorize?response_type=code&client_id=".$container->get('client_id')."&redirect_uri=".urlencode($container->get('redirect_uri'));

    $token_url = $container->get('login_uri')."/services/oauth2/token";
    $revoke_url = $container->get('login_uri')."/services/oauth2/revoke";

    $code = $_GET['code'];

    if (!isset($code) || $code == "") {
        die("Error - code parameter missing from request!");
    }

    $params = "code=".$code
        ."&grant_type=".$container->get('grant_type')
        ."&client_id=".$container->get('client_id')
        ."&client_secret=".$container->get('client_secret')
        ."&redirect_uri=".urlencode($container->get('redirect_uri'));

    $curl = curl_init($token_url);
    curl_setopt($curl, CURLOPT_HEADER, false);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_POST, true);
    curl_setopt($curl, CURLOPT_POSTFIELDS, $params);

    $json_response = curl_exec($curl);

    $status = curl_getinfo($curl, CURLINFO_HTTP_CODE);

    if ($status != 200) {
        die("Error: call to token URL $token_url failed with status $status, response $json_response, curl_error ".curl_error(
                $curl
            ).", curl_errno ".curl_errno($curl));
    }

    curl_close($curl);

    $response = json_decode($json_response, true);

    $access_token = $response['access_token'];
    $instance_url = $response['instance_url'];

    if (!isset($access_token) || $access_token == "") {
        die("Error - access token missing from response!");
    }

    if (!isset($instance_url) || $instance_url == "") {
        die("Error - instance URL missing from response!");
    }

    $output->writeln('Access Token ' . $access_token);
    $output->writeln('Instance Url ' . $instance_url);
}

しかし、タスクを呼び出すたびに、次のエラーが発生しました。

[Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException] 存在しないサービス「login_uri」をリクエストしました。

なんで?ファイルのパラメーターにアクセスできませんparameter.ymlか? どこで失敗していますか?

4

2 に答える 2

1

Artamiel の回答と以下のコメントに従って、CRON タスクとして実行されるコマンドを作成するために必要なものを次に示します (少なくとも、これは私が行った方法です)。

  • まず、SalesforceCommandクラスを宣言します。

    <?php
    class SalesforceCommand extends ContainerAwareCommand
    {
        protected function configure()
        {
            $this
                ->setName('pdone:veeva:sync')
                ->setDescription('Doing some tasks, whatever...');
        }
    
        protected function execute(InputInterface $input, OutputInterface $output)
        {    
            $myService = $this->getContainer()->get('my.service');
    
            $returnValue = $myService->whateverAction();
    
            if($returnValue === true)
                $output->writeln('Return value of my.service is true');
            else
                $output->writeln('An error occured!');
        }
    }
    
  • 次に、必要なバンドルでコントローラーを作成します。

        <?php
        namespace My\MyBundle\Service;          
    
        use Symfony\Component\HttpFoundation\RequestStack;
    
        class ServiceController extends Controller
        {
            private $_rs;
    
            public function __construct(RequestStack $rs)
            {
                $this->_rs = $rs;
            }
    
            public function whateverAction()
            {
                $request = $this->_rs->getCurrentRequest();
    
                // do whatever is needed with $request.
    
                return $expectedReturn ? true : false;
            }
        }
    
  • 最後に、コントローラーをサービスとして登録しますapp/config/services.yml

    services:
        my.service:
            class: My\MyBundle\Service\ServiceController
            arguments: ["@request_stack"]
    

( Symfony 2.4 では、リクエスト サービスを注入する代わりに、request_stack サービスを注入し、getCurrentRequest() メソッドを呼び出してリクエストにアクセスする必要があります)

  • crontab に以下を追加することで、最終的に CRON ジョブとして実行できるようになります (毎分実行するため)。

    * * * * * /usr/local/bin/php /path/to/your/project/app/console pdone:veeva:sync 1>>/path/to/your/log/std.log 2>>/path/to/your/log/err.log
    

それが役立つことを願っています!

于 2015-06-17T13:43:35.397 に答える