DrupalとYandex.PDDの接続方法についてのBylina

少し前に、私はDrupalに基づいた1つの小さな町の都市サイト(もちろん、別のサイト)を作成することを考えていました。 その少し前に、Yandexはドメイン向けのメールの機能を拡張し、APIを介してメールボックスを管理する機能を追加しました。 そして、私の頭の中で考えが浮上しました:なぜですか? ユーザーに都市ポータルの登録を同時に受信して都市ドメインのメールボックスを受信する機会を提供してみませんか? もちろん、アイデア自体は驚くことではありませんが、既成のソリューションはありませんでした。 サイトを立ち上げたことはありませんが、何もせずにコーディングするのは罪です。



ご存じのように、DrupalはCMS、指向の開発者として位置付けられており、広範なAPIのおかげで少なくとも月の基地を管理するシステムを開発できます。 私の投稿では、彼女とDrupal用のモジュール開発の最も基本的な原則を称賛するつもりはありませんが、Drupalの開発を開始することで、この資料はきっと役に立つと思うでしょう。







問題の声明



当然のことながら、モジュールの記述を開始するとき、どの機能を使用するかを決定する必要があります。 このモジュールは、ユーザーが登録できるソーシャルサイト用に設計されています。 したがって、彼は:



もちろん、さらにパンを追加することも可能です(たとえば、システムでパスワードを変更するときにメールボックスのパスワードを変更し、ユーザーデータを編集し、リダイレクトを管理します)が、これは過剰です。



.infoファイル



Drupalモジュールには、モジュールに関するサービス情報を含む.infoファイルが含まれている必要があります。 最小セットは、モジュールの名前、簡単な説明、およびモジュールが記述されているカーネルのバージョンです。 しかし、この場合、もう1つのフィールド-依存関係を指定する必要があります。 モジュールのロジックは、ログインがユーザーのログインと一致するボックスの作成です。 ただし、ユーザーがキリル文字のログインを作成する機会を奪い、Yandexを驚かせないためには、音訳モジュールが必要です。 したがって、yandex_pdd.infoファイルは次のようになります。



name = Yandex PDD description = Yandex PDD mailboxes autocreation. core = 7.x dependencies[] = transliteration
      
      





当然、モジュールをインストールする前に、この音訳をコンピューターにインストールすることを忘れないでください



ファイルのインストールとアンインストール



別の必要なファイルは.install(この場合はyandex_pdd.install)で、モジュールで使用されるデータベースと、モジュールのインストールおよび削除時に必要なアクションを決定します。 動作するには、1つのデータベースと2つの変数が必要です。 まず、基本構造を定義しましょうhook_schema() hook)



 function yandex_pdd_schema() { $schema['yandex_pdd'] = array( 'fields' => array( 'id' => array('type' => 'serial', 'not null' => TRUE), //   'uid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0,), //   'login' => array('type' => 'varchar', 'length' => 100, 'not null' => TRUE), //      'activated' => array('type' => 'varchar', 'length' => 1, 'not null' => TRUE) //    ), 'primary key' => array('id'), ); return $schema; }
      
      





最初の2つの列は、疑問を投げかけるものではないと思います。 3番目の列では、メールボックス自体のログインを記録します。 4列目は個別に分解する必要があります。 CMS Drupalでは、ユーザーのアクティベーションのために、電子メールで送信されたリンクをクリックし、パスワードを設定する必要があります。 アカウントの一部(スパムボットや見知らぬ人の一部)が決してアクティブにならないことはよく知られている事実です。したがって、ユーザーが新しいパスワードを設定するときにボックスを作成することは理にかなっています。 実際、これにより、同じパスワードでボックスを作成できます。 以下でこの問題に触れます。



モジュールが削除されると、スキームに記述されているベースが自動的に削除されます。 しかし、変数、キャッシュされたデータなど hook_uninstall()を使用して削除する必要があります。



 function yandex_pdd_uninstall() { variable_del('yandex_pdd_domain'); variable_del('yandex_pdd_authtoken'); cache_clear_all('yandex_pdd','cache',TRUE); menu_rebuild(); }
      
      





パラメーターyandex_pdd_domainおよびyandex_pdd_authtokenは、それぞれボックスが作成されるドメインとAPIキーを指定します。 それらについては後ほど詳しく説明します。



モジュールに必要な基盤が構築され、モジュールコード自体の記述を開始できます。 予想どおり、拡張子が.module(yandex_pdd.module)のファイルに保存されます。



メニューアイテム



Drupalモジュールをメニューに登録したり、ページを作成したりする必要がある場合は、 hook_menu()フックを使用してリンクをたどるときに、構造全体と必要なアクションを記述する必要があります。 この場合、2つのURLが使用されます。モジュールのセットアップページとメールボックスへのリダイレクトです。



 function yandex_pdd_menu(){ $items = array(); $items['admin/config/content/yandex_pdd'] = array( //   -     'title' => t('Yandex PDD'), // <title>  'page callback' => 'main_config', // ,      'type' => MENU_NORMAL_ITEM, //       CMS 'access callback' => TRUE, //      ); $items['mailbox'] = array( 'title' => 'Yandex PDD login', 'page callback' => 'mailbox_login', 'type' => MENU_CALLBACK, 'access callback' => TRUE, ); return $items; }
      
      





t()システム関数の使用に注意してください。 テキスト要素を現在のシステム言語に翻訳できます。 はい、 メールボックスページにこの機能は必要ありません。



設定ページ



前のセクションでは、モジュールに必要なデータを入力するページがパスadmin / config / content / yandex_pddに沿って配置され、 main_config関数によって処理されることをCMSに伝えました 。 実際、CMSはページが具体的に何をするかを実際には認識していませんが、このパスにアクセスするときは、この関数にアクセスする必要があることを知っています。



 function main_config(){ $form = drupal_get_form('pdd_config_form'); //    $form = drupal_render($form); //   return $form; }
      
      





ページを作成するには、ユーザー定義関数pdd_config_formに対してdrupal_get_form()システム関数を呼び出して、Drupalが理解できるフォームフィールドの配列を取得します。



 function pdd_config_form($form, &$form_state){ $form=array(); $form['pdd_domain'] = array( //   -     '#type' => 'textfield', //   '#title' => t('Domain zone'), //  ,   '#description' => t('A domain zone in which email should be created.'), //   '#default_value' => variable_get('yandex_pdd_domain'), //    '#required' => 1, //   ); $form['authtoken'] = array( '#type' => 'textfield', '#title' => t('Auth Token'), '#description' => t('Authorization token obtained at Yandex.PDD service.'), '#default_value' => variable_get('yandex_pdd_authtoken'), '#required' => 1, ); $form['submit'] = array( '#type' => 'submit', '#value' => t('Submit'), ); return $form; }
      
      





結果はdrupal_render()関数に渡され、配列がページの完成したhtmlコードに配列を収集します。



フォームには2つのフィールドのみが含まれます。







当然、フォームに入力した結果を保存する必要があります。 pdd_config_form_submit関数はこれを担当し、フィールド値をシステム変数に単純に保存します。



 function pdd_config_form_submit($form, &$form_state){ variable_set('yandex_pdd_domain', $form_state['values']['pdd_domain']); variable_set('yandex_pdd_authtoken', $form_state['values']['authtoken']); }
      
      





もう1つの小さなコードはhook_help()フック実装で、admin部分の対応するセクションにモジュールに関するヘルプ情報を表示します。 この機能に関して、私は気にせず、ミニマリズムの道を歩みました。



 function yandex_pdd_help($path, $arg) { switch ($path) { case "admin/help#yandex_pdd": return '<p>'. t("Yandex PDD mailboxes management module.") .'</p>'; break; } }
      
      





私たちは管理部分を扱いました。 カスタムを行う時が来ました。すべての機能を作成段階と作業段階に分けることができます。



ボックスを作成



お気に入りのサイトのドメインであっても、すべてのユーザーが別の電子メールを必要とするわけではありません。 また、未使用のボックスを大量に作成する必要はありません。 したがって、ユーザーの登録フォームにチェックボックスを追加して、ボックスを作成するかどうかをユーザーが選択できるようにします。 Drupalのフォームは、 hook_form_alter()を使用して変更できます。 フォーム記述配列のいくつかの要素の目的についてはすでによく知っています。 詳細については、 フォームのmanページの残り参照してください



 function yandex_pdd_form_alter(&$form, &$form_state, $form_id){ if($form_id=='user_register_form'){ //    $form['account']['createmail']=array( //    '#type' => 'checkbox', '#title' => t('Create a mailbox'), '#description' => t('Check this box if you want to create a mailbox @'.variable_get('yandex_pdd_domain').'.'), '#required' => 0, '#access' => 1, //     '#weight' => 10 //  ( ) ); } }
      
      





小さなチェックボックス用のテキストがたくさん。



ユーザーを登録するときに、フォームにボックスを作成するためのチェックボックスがオンになっているかどうかを確認し、オンになっている場合は、非アクティブなボックスに関するデータをテーブルに入力します。



 function yandex_pdd_user_insert(&$edit, $account, $category){ if($account->createmail){ $transliterated = transliteration_get($account->name, '_'); //   $pattern = '/[^a-zA-Z0-9]/'; //     ,     $transliterated = preg_replace($pattern, '-', $transliterated); //    alphanumeric    $newbox = db_insert('yandex_pdd'); //      $newbox->fields(array('uid' => $account->uid, 'login' => strtolower($transliterated), 'activated' => '0')); //     $res = $newbox->execute(); //   watchdog('yandex_pdd',print_r('Res: '.$res,1)); //       CMS  } }
      
      





ボックスの作成は、ユーザーデータフックhook_field_attach_submit()を使用してフォームを変更することと関連しています。 したがって、ユーザーが最初にデータ編集(パスワード変更)を行う前に、ボックスは作成されません。



 function yandex_pdd_field_attach_submit($entity_type, $entity, $form, &$form_state) { global $user; if($entity_type == 'user' and $user->uid > 0) { //      user $select = db_select('yandex_pdd','ypdd'); $select->addField('ypdd', 'id'); $select->addField('ypdd', 'login'); $select->addField('ypdd', 'activated'); $select->condition('uid', $user->uid); $entries = $select->execute()->fetchAssoc(); //        if (array_key_exists('login', $entries) and $entries['login'] != '' and $entries['activated'] == 0) { //         $mailboxcreate = simplexml_load_file('https://pddimp.yandex.ru/reg_user_token.xml?token='.variable_get('yandex_pdd_authtoken').'&u_login='.$entries['login'].'&u_password='.$form["#user"]->pass); //     XML- if ($mailboxcreate->ok[0]) { //   $num_updated = db_update('yandex_pdd'); $num_updated->fields(array('activated' => '1')); $num_updated->condition('uid', $user->uid); $res = $num_updated->execute(); //     } elseif ($mailboxcreate->error[0]) { //   API foreach($mailboxcreate->error[0]->attributes() as $key => $value) { $mbc[$key] = (string)$value; } watchdog('yandex_pdd',"Can't create new mailbox. Reason: ".$mbc['reason']); //     } else { //      watchdog('yandex_pdd','Unknown error while creating mailbox.'); //    } } } }
      
      





最後に、ユーザーは箱を受け取りましたが、彼はそこに着く方法を本当に知りません。 メールに切り替える機能を実装することは残っています。



仕事の機能



実際には、ブロックを表示し、メールで認証するという2つのユーザー機能しかありません。 最初に、ブロックをhook_block_info() hookで記述する必要があります。



 function yandex_pdd_block_info() { $blocks['mailbox_status'] = array( //    'info' => t('Mailbox status'), //    'cache' => DRUPAL_CACHE_PER_ROLE, //   ); return $blocks; }
      
      





ブロックについては、テーマとファイルをデザインテンプレートで設定する必要があります。 テーマはhook hook_theme()で記述され、システムへのモジュール要素の設計の実装を記述します。



 function yandex_pdd_theme() { return array( 'yandex_pdd_block' => array( //    'variables' => array( //    'newmail' => NULL ), 'template' => 'yandex-pdd-block', //    ) ); }
      
      





そして、実際、 yandex-pdd-block.tpl.phpファイル自体



 <div class="yandexpdd"><?php print t('You have ').'<a href="/mailbox" target="_blank">'.$newmail.t(' new messages').'</a>.'; ?></div>
      
      





ブロックについては、APIに値を1つだけ取得する必要があります-新しい文字の数、そしてフックhook block_view()でブロック自体をレンダリングします



 function yandex_pdd_block_view($delta = '') { global $user; if ($user->uid > 0) { // ,    $select = db_select('yandex_pdd','ypdd'); $select->addField('ypdd', 'login'); $select->condition('uid', $user->uid); $entries = $select->execute()->fetchAssoc(); //    $unreadmailxml = simplexml_load_file('https://pddimp.yandex.ru/get_mail_info.xml?token='.variable_get('yandex_pdd_authtoken').'&login='.$entries['login']); //       if ($unreadmailxml->ok[0]) { //    foreach($unreadmailxml->ok[0]->attributes() as $key => $value) { //   $unreadmail[$key] = (string)$value; } $blocks = array(); $blocks['subject'] = null; $blocks['content'] = theme('yandex_pdd_block', array('newmail' => $unreadmail['new_messages'])); return $blocks; //   } elseif ($unreadmailxml->error[0]) { foreach($unreadmailxml->error[0]->attributes() as $key => $value) { $unreadmail[$key] = (string)$value; } watchdog('yandex_pdd',"Can't get new mail info. Reason: ".$unreadmail['reason']); } else { watchdog('yandex_pdd','Unknown error while loading new mail info'); } } }
      
      





生成されたブロックは次のようになります。







最後のタッチは、 メールボックスシステムリンクです。これにより、ユーザーはYandex.Mailページにリダイレクトされ、ワンタイムトークンを使用して承認されます。 覚えている(または覚えていない)ため、このリンクをmailbox_login関数で処理するように以前に設定しました。 トークンの有効期間はわずか30秒です。したがって、トークンを受け取った後、ユーザーはすぐに認証ページにリダイレクトされる必要があります。



 function mailbox_login(){ global $user; global $base_url; if ($user->uid > 0) { $select = db_select('yandex_pdd','ypdd'); $select->addField('ypdd', 'login'); $select->condition('uid', $user->uid); $entries = $select->execute()->fetchAssoc(); $tokenxml = simplexml_load_file('https://pddimp.yandex.ru/api/user_oauth_token.xml?token='.variable_get('yandex_pdd_authtoken').'&domain='.variable_get('yandex_pdd_domain').'&login='.$entries['login']); //     if ($tokenxml->xpath('status/success')) { $tokenarr = $tokenxml->xpath('domains/domain/email/oauth-token'); header('Location: http://passport.yandex.ru/passport?mode=oauth&type=trusted-pdd-partner&error_retpath='.urlencode($base_url.'/').'&access_token='.(string)$tokenarr[0]); //    . drupal_exit(); //     CMS } elseif ($tokenxml->xpath('status/error')) { watchdog('yandex_pdd',"Can't get short-term auth token info. Reason: ".(string)$tokenxml->xpath('action/status/error')); } } }
      
      







おわりに



ここで終わりを言います。 指定されたファイル名に従って収集されたコードの断片は、既製のモジュールを提供するはずです。 それが誰かに役立つことを望み、コードに関するコメントや推奨事項を喜んで聞きます。



All Articles