Drupal 8 カスタムテーブルのデータ表示、追加、編集、削除

Drupal 8 カスタムテーブルのデータ表示、追加、編集、削除

前回の記事で、カスタムテーブルの一覧表示を行いましたが、今回は、カスタムテーブルに対して、レコードの追加、編集、削除および表示を行います。

実行イメージ

今回作成したカスタムモジュールのサンプルは、こちらのリンクからご確認できます。

画面イメージ

twigテンプレートを使用した表示

社員情報をtwigテンプレートを使用して表示します。

employee.routing.ymlに以下を記述します。(今回作成するカスタムモジュールのモジュール名は「employee」のため、ファイル名「employee.routing.yml」とします)


employee.view:
  path: '/employee/view/{employee_id}'
  defaults:
    _controller: '\Drupal\employee\Controller\EmployeeViewController::view'
    _title: 'Employee情報の表示'
  requirements:
    _permission: 'access content'
    employee_id: \d{5}

Controllerに社員IDを引数として渡すために、pathに{employee_id}を記述しています。

引数の社員IDは、数字5桁として制限したいので、requirementsに、正規表現でemployee_idについて、「\d{5}」と記述します。

今回はtwigにデータを渡したいので、employee.moduleに以下のように記述します。変数名は、'employee'とします。


<?php

/**
 * Implements hook_theme().
 */
function employee_theme($existing, $type, $theme, $path) {
  return [
    'employee_template' => [
      'variables' => ['employee' => NULL],
    ],
  ];
}

twigテンプレートファイルは、モジュールの中にtemplatesディレクトリを作成して、その中にファイル名employee-template.html.twigとして作成します。このファイル名は、上記のemployee.modueの中で記述した'employee_template'のアンダースコアをハイフン「-」としたものとなります。

今回、以下のようなtwigテンプレートemployee-template.html.twigを作成します。


<p>社員情報を表示します。</p>

<div class="employee">
<table class="table table-hover">
        <tbody>
                <tr>
                        <td colspan="4" class="kana">{{ employee.kana }}</td>
                </tr>
                <tr>
                        <td colspan="4" class="name">{{ employee.name }}</td>
                </tr>
                <tr>
                        <th scope="row">社員ID</th>
                        <td colspan="3">{{ employee.employee_id }}</td>
                </tr>
                <tr>
                        <th scope="row">部門コード</th>
                        <td>{{ employee.dept_code }}</td>
                        <th scope="row">職位</th>
                        <td>{{ employee.position }}</td>
                </tr>
                <tr>
                        <th scope="row">電話番号</th>
                        <td colspan="3">{{ employee.telephone }}</td>
                </tr>
                <tr>
                        <th scope="row">メールアドレス</th>
                        <td colspan="3">{{ employee.mail }}</td>
                </tr>
        </tbody>
</table>
</div>

<a href="/ja/employee/list" class="link-btn">一覧へ戻る</a>

Controllerクラスとして、以下のようなファイルを作成し、employeeテーブルから社員IDが引数で渡された$employee_idに等しいデータを検索します。fetchAssoc()により、結果を連想配列として取得できるので、取得した結果をそのままtwigテンプレートへ渡します。


<?php

namespace Drupal\employee\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Database\Database;

/**
 * EmployeeViewControllerクラス
 */
class EmployeeViewController extends ControllerBase {

  /**
   * employeeデータの表示
   *
   * @return array
   *   Return markup array.
   */
  public function view($employee_id) {

    // employeeテーブルから社員IDが$employee_idに等しいデータをselect
    $conn = Database::getConnection();
    $query = $conn->select('employee', 'emp');
    $query->condition('employee_id', $employee_id)->fields('emp');
    // 連想配列として取得
    $employee = $query->execute()->fetchAssoc();


    // 'employee-template.html.twig'に変数$employeeを渡す
    return [
      '#theme' => 'employee_template',
      '#employee' => $employee,
    ];
  }

}

上記employee.routing.ymlに、「path: '/employee/view/{employee_id}'」と指定してあるので、社員ID「00001」の表示のために、/employee/view/00001にアクセスすると、以下のような画面が表示されます。

view

レコード追加用のフォームの作成

次に、社員のレコード追加のためのフォームを作成します。フォームの作成のために、DrupalのFormBaseクラスを継承したフォームクラスを作成します。フォームクラスでは、以下の3つのメソッドの実装が必須です。

  • getFormId()
  • buildForm()
  • submitForm()

入力チェック等のバリデーションを行う場合は、以下のメソッドを実装します。

  • validateForm()

以下のようにファイルEmployeeAddForm.phpを作成します。


<?php
/**
 * @file
 * Contains \Drupal\employee\Form\EmployeeAddForm.
 */
namespace Drupal\employee\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Database\Database;
use Drupal\Core\Url;

class EmployeeAddForm extends FormBase {


  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'employee_add_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {

    $form['employee_id'] = array(
      '#type' => 'textfield',
      '#title' => $this->t('社員ID'),
      '#required' => TRUE,
    );

    $form['dept_code'] = array(
      '#type' => 'textfield',
      '#title' => $this->t('部門コード'),
      '#required' => TRUE,
    );

    $form['name'] = array(
      '#type' => 'textfield',
      '#title' => $this->t('名前'),
      '#required' => TRUE,
    );

    $form['kana'] = array(
      '#type' => 'textfield',
      '#title' => $this->t('カナ'),
      '#required' => TRUE,
    );

    $form['position'] = array(
      '#type' => 'textfield',
      '#title' => $this->t('職位'),
      '#required' => TRUE,
    );

    $form['telephone'] = array(
      '#type' => 'textfield',
      '#title' => $this->t('電話')
    );

    $form['mail'] = array(
      '#type' => 'textfield',
      '#title' => $this->t('メール')
    );

    $form['actions']['#type'] = 'actions';
    $form['actions']['submit'] = array(
      '#type' => 'submit',
      '#value' => $this->t('保存'),
      '#button_type' => 'primary',
    );
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {

    // 入力された'employee_id'がすでに存在しているかを確認
    $employee_id = $form_state->getValue('employee_id');
    $conn = Database::getConnection();
    $query = $conn->select('employee', 'emp');
    $query->condition('employee_id', $employee_id)->fields('emp');;
    $record = $query->execute()->fetchAssoc();

    // エラーメッセージの出力
    if ( 5 != strlen($form_state->getValue('employee_id')) ) {
      $form_state->setErrorByName('employee_id', '社員IDは5文字で入力して下さい。');
    } else if ( $record ) {
      $form_state->setErrorByName('employee_id', '入力された社員IDはすでに存在しています:' . $employee_id);
    }

  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {

    $fields['employee_id'] = $form_state->getValue('employee_id');
    $fields['dept_code'] = $form_state->getValue('dept_code');
    $fields['name'] = $form_state->getValue('name');
    $fields['kana'] = $form_state->getValue('kana');
    $fields['position'] = $form_state->getValue('position');
    $fields['$telephone'] = $form_state->getValue('telephone');
    $fields['$mail'] = $form_state->getValue('mail');

    $query = \Drupal::database()->insert('employee');
    $query->fields($fields)->execute();


    drupal_set_message($this->t('保存しました: 社員ID ' . $fields['employee_id']));

    // 一覧のルート名を指定してリダイレクト
    $form_state->setRedirect('employee.list');

  }
}

getFormId()では、Drupalが一意に識別できるように、ユニークなIDを返します。

buildForm()では、Drupalのレンダリング配列の形式で、入力用のテキストフィールドおよびsubmitボタンを記述しています。詳細はRender API overviewを参照して下さい。

サンプル用に、入力必須フィールドも設定しました。これに合わせて、employeeテーブルのNOT NULL成約も変更しています。

validateForm()では、入力チェックを行なっています。今回はサンプルとして、以下のチェックを行なっています。

  • employee_idは5文字
  • employee_idは重複不可

submitForm()では、渡ってきた値でemployeeテーブルにインサートを行なっています。そして、画面にメッセージを表示し、一覧画面へリダイレクトしています。

employee.routing.ymlには以下を追記します。


employee.add:
  path: '/employee/add'
  defaults:
    _form: '\Drupal\employee\Form\EmployeeAddForm'
    _title: 'Employeeの追加'
  requirements:
    _permission: 'access content'

_formキーには、上記のEmployeeAddFormを指定します。

上記で指定したパス'/employee/add'にアクセスすると、以下のような画面が表示されます。

追加画面

編集用フォームの作成

次に、社員情報の編集のためのフォームを作成します。上記と同様、フォームの作成のために、DrupalのFormBaseクラスを継承したフォームクラスを作成します。

以下のようにファイルEmployeeUpdateForm.phpを作成します。


<?php
/**
 * @file
 * Contains \Drupal\employee\Form\EmployeeUpdateForm.
 */
namespace Drupal\employee\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Database\Database;
use Drupal\Core\Url;

class EmployeeUpdateForm extends FormBase {

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'employee_update_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state, $employee_id = NULL) {

    // 引数で渡された$employee_idから社員情報を取得
    $conn = Database::getConnection();
    $query = $conn->select('employee', 'emp');
    $query->condition('employee_id', $employee_id)->fields('emp');;
    $record = $query->execute()->fetchAssoc();

    $dept_code = $record['dept_code'];
    $name = $record['name'];
    $kana = $record['kana'];
    $position = $record['position'];
    $telephone = $record['telephone'];
    $mail = $record['mail'];

    $form['employee_id'] = array(
      '#type' => 'textfield',
      '#default_value' => $employee_id,
      '#title' => $this->t('社員ID'),
      '#disabled' => TRUE
    );

    $form['dept_code'] = array(
      '#type' => 'textfield',
      '#default_value' => $dept_code,
      '#title' => $this->t('部門コード'),
      '#required' => TRUE,
    );

    $form['name'] = array(
      '#type' => 'textfield',
      '#default_value' => $name,
      '#title' => $this->t('名前'),
      '#required' => TRUE,
    );

    $form['kana'] = array(
      '#type' => 'textfield',
      '#default_value' => $kana,
      '#title' => $this->t('カナ'),
      '#required' => TRUE,
    );

    $form['position'] = array(
      '#type' => 'textfield',
      '#default_value' => $position,
      '#title' => $this->t('職位'),
      '#required' => TRUE,
    );

    $form['telephone'] = array(
      '#type' => 'textfield',
      '#default_value' => $telephone,
      '#title' => $this->t('電話')
    );

    $form['mail'] = array(
      '#type' => 'textfield',
      '#default_value' => $mail,
      '#title' => $this->t('メール')
    );

    $form['actions']['#type'] = 'actions';
    $form['actions']['submit'] = array(
      '#type' => 'submit',
      '#value' => $this->t('更新'),
      '#button_type' => 'primary',
    );
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {


  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {

    $fields['employee_id'] = $form_state->getValue('employee_id');
    $fields['dept_code'] = $form_state->getValue('dept_code');
    $fields['name'] = $form_state->getValue('name');
    $fields['kana'] = $form_state->getValue('kana');
    $fields['position'] = $form_state->getValue('position');
    $fields['$telephone'] = $form_state->getValue('telephone');
    $fields['$mail'] = $form_state->getValue('mail');

    $query = \Drupal::database()->update('employee');
    $query->fields($fields);
    $query->condition('employee_id', $fields['employee_id']);
    $result = $query->execute();


    drupal_set_message($this->t('更新しました: 社員ID ' . $employee_id));

    // 一覧のルート名を指定してリダイレクト
    $form_state->setRedirectUrl(Url::fromRoute('employee.list'));

  }
}

編集画面では、元の値を表示するために、buildForm()で、引数$employee_idを受け取り、employeeテーブルからselectした結果をそれぞれのフィールドに#default_valueとして表示しています。Primary Keyの社員IDについては、編集不可とするために、#disabledTRUEにセットしています。

submitForm()では、渡ってきた値でemployeeテーブルのアップデートを行なっています。そして、画面にメッセージを表示し、一覧画面へリダイレクトしています。

employee.routing.ymlには以下を追記します。


employee.update:
  path: '/employee/update/{employee_id}'
  defaults:
    _form: '\Drupal\employee\Form\EmployeeUpdateForm'
    _title: 'Employeeの更新'
  requirements:
    _permission: 'access content'
    employee_id: \d{5}

_formキーには、上記のEmployeeUpdateFormを指定します。

パラメータとして、{employee_id}pathに設定します。パス'/employee/update/00001'にアクセスすると、以下のような画面が表示されます。

編集画面

削除用フォームの作成

次に、社員情報の削除のためのフォームを作成します。今回は、ユーザー確認用のフォームとして使用されるConfirmFormBaseクラスを継承したフォームクラスを作成します。ConfirmFormBaseクラスを継承したクラスでは、以下の4つのメソッドの実装が必須です。

  • getFormId()
  • getQuestion()
  • getCancelUrl
  • submitForm()

その他、実装することがオプションのメソッドも含むConfirmFormInterfaceについては、ConfirmFormInterface API documentを参照して下さい。

以下のようにファイルEmployeeDeleteForm.phpを作成します。


<?php
namespace Drupal\employee\Form;

use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Form\ConfirmFormBase;
use Drupal\Core\Url;

/**
 * Class EmployeetDeleteForm.
 *
 * @package Drupal\employee\Form
 */
class EmployeeDeleteForm extends ConfirmFormBase {

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'employee_delete_form';
  }

  protected $employee_id;

  /**
   * {@inheritdoc}
   */
  public function getQuestion() {
    return t('社員ID:%employee_id のデータを削除します。よろしいですか?', [
      '%employee_id' => $this->employee_id,
    ]);
  }

  /**
   * {@inheritdoc}
   */
  public function getCancelUrl() {
    return new Url('employee.list');
  }

  /**
   * {@inheritdoc}
   */
  public function getDescription() {
    return t('削除されたデータは元に戻すことはできません。');
  }

  /**
   * {@inheritdoc}
   */
  public function getConfirmText() {
    return t('削除');
  }

  /**
   * {@inheritdoc}
   */
  public function getCancelText() {
    return t('キャンセル');
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state, $employee_id = NULL) {

    // 引数で渡ってきた$employee_idをインスタンス変数にセット
    $this->employee_id = $employee_id;

    return parent::buildForm($form, $form_state);
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {

    // レコードの削除
    $query = \Drupal::database();
    $query->delete('employee')->condition('employee_id', $this->employee_id)->execute();

    drupal_set_message($this->t('データが削除されました。社員ID:' . $this->employee_id));

    // 一覧のルート名を指定してリダイレクト
    $form_state->setRedirect('employee.list');
  }

}

getQuestion()で削除対象の社員IDを表示するために、buildForm()では、引数として渡ってきた$employee_idをインスタンス変数に保持します。

submitForm()では、渡ってきた$employee_idのレコードをemployeeテーブルから削除します。そして、画面にメッセージを表示し、一覧画面へリダイレクトしています。

employee.routing.ymlには以下を追記します。


employee.delete:
  path: '/employee/delete/{employee_id}'
  defaults:
    _form: '\Drupal\employee\Form\EmployeeDeleteForm'
    _title: 'Employeeの削除'
  requirements:
    _permission: 'access content'
    employee_id: \d{5}

パス'/employee/delete/00001'にアクセスすると、以下のような画面が表示されます。

削除

一覧表示の変更

上記で作成した表示/追加/編集/削除へのリンクを一覧に追加します。

EmployeeListController.phpを以下のように記述します。


<?php

namespace Drupal\employee\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Url;
use Drupal\Core\Link;

/**
 * EmployeeListControllerクラス
 */
class EmployeeListController extends ControllerBase {

  /**
   *  employeeテーブルからのリストの取得
   */
  function queryEmployeeList($header, $employee_id, $dept_code) {

    // employeeテーブルのqueryを行う
    $query = \Drupal::database()->select('employee', 'emp');
    $query->fields('emp', ['employee_id','dept_code','name','kana','position','telephone','mail']);
    // ヘッダーにソート項目を指定
    $table_sort = $query->extend('Drupal\Core\Database\Query\TableSortExtender')->orderByHeader($header);
    // ページャーを使用。表示件数:5行
    $pager = $table_sort->extend('Drupal\Core\Database\Query\PagerSelectExtender')->limit(5);

    // フィルターとして社員IDが入力された場合は、検索条件にemployee_idを追加する
    if ( !empty($employee_id) ) {
      $pager->condition('employee_id', $employee_id);
    }
    // フィルターとして部門コードが入力された場合は、検索条件にLIKEでdept_codeを追加する
    if ( !empty($dept_code) ) {
      $pager->condition('dept_code', '%' . $dept_code . '%', 'LIKE');
    }

    // 検索の実行
    $results = $pager->execute()->fetchAll();

    // 出力用の配列を初期化
    $output = array();

    // query結果を出力用の配列にセット
    foreach ($results as $row) {

      // 表示画面へのリンク
      $view = Url::fromRoute('employee.view',['employee_id' => $row->employee_id] );
      $name_link = \Drupal::l($row->name, $view);

      // 編集画面、削除画面へのリンク
      $edit = Url::fromRoute('employee.update',['employee_id' => $row->employee_id] );
      $delete = Url::fromRoute('employee.delete',['employee_id' => $row->employee_id] );

//    Drupal::l はDeprecated のため、Link::fromTextAndUrlを使用するべきのようだが、以下のコードだとエラーになるため
//    今回は、Drupal::l を使用する
//    $edit_link = Link::fromTextAndUrl('編集', $edit);
//    $delete_link = Link::fromTextAndUrl('削除', $delete);
      $edit_link = \Drupal::l('編集', $edit);
      $delete_link = \Drupal::l('削除', $delete);

      $opeLink = t('@linkEdit  @linkDelete', array('@linkEdit' => $edit_link, '@linkDelete' => $delete_link));

      $output[] = [
        'employee_id' => $row->employee_id,
        'dept_code' => $row->dept_code,
        'name' => $name_link,
        'kana' => $row->kana,
        'position' => $row->position,
        'telephone' => $row->telephone,
        'mail' => $row->mail,
        'opt' => $opeLink,
      ];
    }

    return $output;
  }

  /**
   * employeeテーブルの一覧表示
   *
   * @return array
   *   Return markup array.
   */
  public function list() {

    // フィルターFormからのパラメータの取得
    $employee_id = \Drupal::request()->query->get('employee_id');
    $dept_code = \Drupal::request()->query->get('dept_code');
    // ゼロパディング
    if ( !empty($employee_id) ) {
      $employee_id = sprintf('%05d',$employee_id);
    }

    //filter controllerの読み込み
    $form['form'] = $this->formBuilder()->getForm('Drupal\employee\Form\EmployeeFilterForm');

    // 社員の追加
    $form['employee'] = [
      '#title' => $this->t('社員の追加'),
      '#type' => 'link',
      '#url' => Url::fromRoute('employee.add'),
      '#attributes' => [
        'class' => ['link-btn'],
      ]
    ];

    // 'field'で指定された項目がソート項目となる
    $header = [
      [ 'data' => '社員ID',     'field' => 'employee_id', 'sort' => 'asc' ],
      [ 'data' => '部門コード', 'field' => 'dept_code' ],
      [ 'data' => '名前',       ],
      [ 'data' => 'カナ',       'field' => 'kana' ],
      [ 'data' => '職位',       ],
      [ 'data' => '電話',       ],
      [ 'data' => 'メール',     ],
      [ 'data' => '操作',       ],
    ];

    $output = $this->queryEmployeeList($header, $employee_id, $dept_code);

    $form['table'] = [
      '#type' => 'table',
      '#header' => $header,
      '#rows' => $output,
      '#empty' => 'データがありません',
    ];

    // pagerの表示
    $form['pager'] = [
      '#type' => 'pager'
    ];

    return $form;
  }

}

一覧画面に、表示画面、編集画面、削除画面へのリンクを追加するために、queryEmployeeList()に、リンクの記述を行っています。

編集画面、削除画面へのリンクは、「操作」列に表示するために、list()の中で、headerに「操作」列を追加しています。

追加画面へのリンクボタンもlist()に記述を行なっています。ボタンのためのcssを設定するために#attributesでクラスの設定を行なっています。

employee.routing.ymlには以下のように記述しています。


employee.list:
  path: '/employee/list'
  defaults:
    _controller: '\Drupal\employee\Controller\EmployeeListController::list'
    _title: 'Employeeの一覧'
  requirements:
    _permission: 'access content'
  options:
    no_cache: 'TRUE'

ここでは、「no_cache: 'TRUE'」の指定を追加し、このページはキャッシュしないようにしています。これを指定しない状態では、編集後に一覧に戻ると編集結果が反映されていなかったために、追加しています。

フィルターの追加

上記のEmployeeListController.phpのqueryEmployeeList()内で、検索条件にemployee_idおよびdept_codeが追加されていますが、このフォームの表示のために、以下のような EmployeeFilterForm.phpを記述します。


<?php
/**
 * @file
 * Contains \Drupal\employee\Form\EmployeeFilterForm.
 */
namespace Drupal\employee\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;

class EmployeeFilterForm extends FormBase {

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'employee_filter_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {

    $form['filters']['employee_id'] = [
        '#title'         => '社員ID',
        '#type'          => 'search'

    ];
    $form['filters']['dept_code'] = [
        '#title'         => '部門コード',
        '#type'          => 'search'
    ];
    $form['filters']['actions'] = [
        '#type'       => 'actions'
    ];

    $form['filters']['actions']['submit'] = [
        '#type'  => 'submit',
        '#value' => $this->t('絞り込み')

    ];

    return $form;

  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {


  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {

    $employee_id = $form_state->getValue('employee_id');
    $dept_code = $form_state->getValue('dept_code');
    $url = Url::fromRoute('employee.list')
          ->setRouteParameters(array('employee_id'=>$employee_id,'dept_code'=>$dept_code));

    // パラメータをセットして一覧へリダイレクト
    $form_state->setRedirectUrl($url);

  }
}

ファイル一覧

以上で、今回のカスタムモジュールは完成です。ファイル一覧は以下となります。


modules/
└──  custom/
     └──  employee/
          ├── employee.info.yml
          ├── employee.module
          ├── employee.routing.yml
          ├── src/
          │   ├── Controller/
          │   │   ├── EmployeeListController.php
          │   │   └── EmployeeViewController.php
          │   └── Form/
          │       ├── EmployeeAddForm.php
          │       ├── EmployeeDeleteForm.php
          │       ├── EmployeeFilterForm.php
          │       └── EmployeeUpdateForm.php
          └── templates/
              └── employee-template.html.twig

ソースファイル

上記のemployeeモジュールのソースファイルを以下に置きました。

カテゴリー

コメント

Lilly Cialis 10mg Et 20mg https://newfasttadalafil.com/ - Cialis Nfucrt <a href=https://newfasttadalafil.com/>Cialis</a> Spwjzr https://newfasttadalafil.com/ - where to buy cialis cheap
名前
blenuiple
Blood tests look for hormone deficiency <a href=http://buycialis.sbs>daily cialis online</a>
名前
Whohoxrix
Within 1 hour she developed agitation, twitching, shakiness, sweating, and generalized erythema with hyperthermia 38 C <a href=https://cialiss.sbs>buy cialis online</a>
名前
Whohoxrix
★品質を重視、納期も厳守、お客様第一主義を貫きは当社の方針です。★驚きの低価格で商品をお客様に提供致します!★早速に購入へようこそ!ブランドスーパーコピーバッグ、財布、時計プラダ スーパーコピー,プラダ 財布 コピー,プラダ 新作 財布ブランド財布コピー,ブランド スーパーコピー 財布,プラダ スーパーコピー 財布,シャネル財布コピールイヴィトン 財布 コピー,ルイヴィトン 財布 コピー 代引き,ルイヴィトン財布スーパーコピー }}}}}}
https://www.bagssjp.com/product/detail-2650.html
https://www.bagssjp.com/product/detail-10129.html
https://www.bagssjp.com/product/detail-8718.html
https://www.bagssjp.com/product/detail-1971.html
https://www.bagssjp.com/product/detail-7148.html
名前
Bagssjpmyday
★品質を重視、納期も厳守、お客様第一主義を貫きは当社の方針です。★驚きの低価格で商品をお客様に提供致します!★早速に購入へようこそ!ブランドスーパーコピーバッグ、財布、時計プラダ スーパーコピー,プラダ 財布 コピー,プラダ 新作 財布ブランド財布コピー,ブランド スーパーコピー 財布,プラダ スーパーコピー 財布,シャネル財布コピールイヴィトン 財布 コピー,ルイヴィトン 財布 コピー 代引き,ルイヴィトン財布スーパーコピー }}}}}}
https://www.copy2021.com/product/detail/4994.htm
https://www.copy2021.com/product/detail/21987.htm
名前
copy2021Apody

コメントを追加

CAPTCHA
この質問はあなたが人間の訪問者であるかどうかをテストし、自動化されたスパム送信を防ぐためのものです。
画像CAPTCHA
画像内に表示されている文字列を入力してください。