メインコンテンツに移動

メインナビゲーション

  • ホーム
  • サイトマップ
  • ビデオ
  • ご連絡

パンくず

  • ホーム
  • DrupalのEntityAPIでエンティティ新規作成後にIDの取得およびEntityMetadataWrappersの使用

DrupalのEntityAPIでエンティティ新規作成後にIDの取得およびEntityMetadataWrappersの使用

drupal
development
entity type

やりたいこと:エンティティ(Entity)新規作成後に作成したエンティティの詳細画面に遷移

  • hook_entity_info()でエンティティを定義します
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MOUDULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',
                'label callback' => 'entity_class_label', // see MyVocabularyEntity class
                'uri callback' => 'entity_class_uri',      // see MyVocabularyEntity class
                'controller class' => 'MyVocabulryController',
                'base table' => 'my_vocabulary',
                'fieldable' => TRUE,
                'entity keys' => array(
                    'id' => 'entity_id',
                    'label' => 'vocabulary',
                ),
                'bundles' => array(
                    'my_vocabulary' => array(
                        'label'=>'My Vocabulary',
                        'admin' => array(
                            'path' => 'admin/structure/my-vocabulary/manage',
                            'access arguments' => array('administer my vocabulary'),
                            'controller class' => 'EntityDefaultUIController',
                        ),
                    ),
                ),
                'view modes' => array(
                    'full' => array(
                        'label' => t('Default'),
                        'custom settings' => FALSE,
                    ),
                ),
                'module' => 'my_vocabulary',
                'access arguments' => array('administer my vocabulary'),
            ),
    
        );
    }
  • hook_menu()で新規エンティティ作成フォームを定義します
    /**
     * Implements hook_menu().
     */
    function YOUR_MODULE_NAME_menu()
    {
        // for my my vocabulary entity
        $items['my-vocabularies/add'] = array(
            'title' => t('Add Vocabulary'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form') ,
            'access arguments' => array('update my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary'] = array(
            'title' => 'My Vocabulary',
            'page callback' => 'my_vocabulary_page_view',
            'page arguments' => array(2) ,
            'access arguments' => array('view my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary/view'] = array(
            'title' => 'View',
            'type' => MENU_DEFAULT_LOCAL_TASK,  //メニュータブの作成
        );
        $items['my-vocabularies/%my_vocabulary/edit'] = array(
            'title' => t('Edit'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form', 2) ,
            'access arguments' => array('edit my vocabulary'),
            'type' => MENU_LOCAL_TASK,
        );
    
        return $items;
    }
  • エンティティ(My Vocabulary)の新規作成/更新フォームは通常のFormAPIより作成します(紹介は省略します)
  • エンティティ作成/更新はentity_save()関数で行います
    /**
     * vocabulary submit handler.
     */
    function vocabulary_form_submit($form, &$form_state) {
        // データ入力フォームで埋め込んだエンティティを取得
        $vocabulary = $form_state['my_vocabulary'];
        
         // 新規作成の場合、$vocabularyオブジェクトがない
        if( $vocabulary == null ) $vocabulary= entity_create( "my_vocabulary", array() );
    
        // 入力フォームの値を$vocabularyにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        entity_save( 'my_vocabulary', $vocabulary );
    
        // エンティティの内容の詳細が画面に遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary); // 新規作成の場合にエラー発生
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
  • 更新の場合は問題なくできましたが、新規作成の場合はエラーが発生しました

問題点:エンティティ作成/更新関数(entity_save())が新規作成したエンティティのIDを返さない

  • 上記のエンティティデータ更新関数(entity_save())がデータ更新成功の場合TUREのみ返します
  • hook_entity_info()で定義した「'uri callback' => 'entity_class_uri'」ではエンティティのIDが必要なので、ここでURIの取得はできません
    class MyVocabularyEntity extends Entity{
        // 'label callback' => 'entity_class_label'
        protected function defaultLabel()
        {
            return $this->vocabulary; // vocabulary名を返す
        }
    
        // 'uri callback' => 'entity_class_uri',
        protected function defaultUri()
        {
            return array("path"=>"chinese/vocabularies/".$this->vid); // vocabulary表示URLを返す
        }
    }

解決:データ更新ロジックを「Entity metadata wrappers」にします

  • EntityAPIでは、Entity metadata wrappersが非常に便利な存在です
    • 本家での紹介記事を参考してください
  • 上記のエンティティデータ更新ロジックを以下のように変更
    /**
     * vocabulary submit handler.
     */
    function my_vocabulary_form_submit($form, &$form_state) {
    
        $vocabulary = $form_state['my_vocabulary'];
        if( $vocabulary == null  )  $vocabulary = entity_create('my_vocabulary',array());
    
        // エンティティ入力フォームの値をエンティティにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        // Entity Metadata Wrapper の使用
        $entity = entity_metadata_wrapper('my_vocabulary',  $vocabulary);
        $entity->save();
    
        // 新規作成したエンティティIDをエンティティオブジェクトにセット
        $vocabulary->entity_id = $entity->getIdentifier() ;
    
        // エンティティの詳細画面のURIを取得、遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary );
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
    
  • 「Entity Metadata Wrapper」のデータ更新($entity->save())実行後に、エンティティのIDが返されたので、そのままに取得することができます

「Entity Metadata Wrapper」でIDとラベルの取得方法

  • hook_entity_info()でエンティティの識別キー: IDが定義されています。また画面タイトルとしてよく使用されているラベル(label)も定義されていますが、必須ではありません
  • 「Entity Metadata Wrapper」オブジェクトに変換後に、エンティティIDとラベルの取得方法が通常のような方法ではありません
    「Entity metadata wrappers」オブジェクトのID、ラベルの取得方法
    // Unified way of getting $node->title, $user->name, ...
    // wrapper->label_name ではエラーになります
    $wrapper->label();
    
    // Unified way of getting $node->nid, $user->uid, ...
    // wrapper->id ではエラーになる
    $wrapper->getIdentifier();
  • エンティティのプロパティがprivateで隠していますので、直接に取得はできません
drupal
development
entity type

関数(entity_metadata_wrapper())よりエンティティ(Entity)のデータ更新が簡単にできるようになります

  • ネット上で関数(entity_metadata_wrapper())がよく紹介されています
  • ラップされたエンティティのプロパティ/拡張フィールドのアクセス(set/get)が簡単になりました
  • ラップされたエンティティがデータ更新メソッドも持っています(EntityDrupalWrapper::save())
    • entity_save(), drupal_write_record(), db_insert() db_update() の組み合わせです
      ラップされたエンティティのデータ更新機能はentity_seve(),drupal_write_record(),db_insert(),db_update()の組み合わせ
  • データ保存後に、新規作成の場合はエンティティのIDが返還されなく、自分で取得しなければならない
    • 例:DrupalのEntityAPIでエンティティ新規作成後にIDの取得およびEntityMetadataWrappersの使用

entity_save()がEntityからのオバーライドを呼び出す

  • hook_entity_info()ではEntityクラスの定義をします。
  • ここで、データ更新時のロジックをオバーライドすることができます(例:Entityの更新時刻の設定など)
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MODULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',  // Entityクラスの継承
                 ・・・・・・・・・
            ),
        );
    }
    
    /**
     * hook_entity_info()に定義された'entity class'
     */
    class MyVocabularyEntity extends Entity{
        //  データ更新ロジックのオバーライド
        public function save()
        {
            $this->updated = time() ;   // 更新時刻の設定
            return parent::save();
        }
    
    }

drupal_write_record()が定義されたテーブルスキーマを呼び出し、エンティティの主キーがあるか否かでupdate/insertを決定

  • drupal_write_record()がまずテーブルのスキーマ(モジュールのインストールファイルにあるhook_schema())を呼び出して、テーブルフィールドデータに、エンティティの値をセットします
    • モジュールのインストールファイルにhook_schema()が定義しないと、データ更新はできないようです
    • EntityMetadataWrapperにあるテーブルフィールドを利用していないです。それはdrupa_write_record()がEntityのためのものではなく、ノードタイプなどのデータにも対応しているからです
  • エンティティ(Entity)の主キー(hook_entity_info()で定義したentity::id)がなければdb_insert()で、あればdb_update()データ更新を行います
    //  empty($primary_keys) ? db_insert() : db_update()  
    function drupal_write_record($table, &$record, $primary_keys = array())

 

 

drupal
development
entity type

やりたいこと:エンティティ(Entity)新規作成後に作成したエンティティの詳細画面に遷移

  • hook_entity_info()でエンティティを定義します
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MOUDULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',
                'label callback' => 'entity_class_label', // see MyVocabularyEntity class
                'uri callback' => 'entity_class_uri',      // see MyVocabularyEntity class
                'controller class' => 'MyVocabulryController',
                'base table' => 'my_vocabulary',
                'fieldable' => TRUE,
                'entity keys' => array(
                    'id' => 'entity_id',
                    'label' => 'vocabulary',
                ),
                'bundles' => array(
                    'my_vocabulary' => array(
                        'label'=>'My Vocabulary',
                        'admin' => array(
                            'path' => 'admin/structure/my-vocabulary/manage',
                            'access arguments' => array('administer my vocabulary'),
                            'controller class' => 'EntityDefaultUIController',
                        ),
                    ),
                ),
                'view modes' => array(
                    'full' => array(
                        'label' => t('Default'),
                        'custom settings' => FALSE,
                    ),
                ),
                'module' => 'my_vocabulary',
                'access arguments' => array('administer my vocabulary'),
            ),
    
        );
    }
  • hook_menu()で新規エンティティ作成フォームを定義します
    /**
     * Implements hook_menu().
     */
    function YOUR_MODULE_NAME_menu()
    {
        // for my my vocabulary entity
        $items['my-vocabularies/add'] = array(
            'title' => t('Add Vocabulary'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form') ,
            'access arguments' => array('update my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary'] = array(
            'title' => 'My Vocabulary',
            'page callback' => 'my_vocabulary_page_view',
            'page arguments' => array(2) ,
            'access arguments' => array('view my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary/view'] = array(
            'title' => 'View',
            'type' => MENU_DEFAULT_LOCAL_TASK,  //メニュータブの作成
        );
        $items['my-vocabularies/%my_vocabulary/edit'] = array(
            'title' => t('Edit'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form', 2) ,
            'access arguments' => array('edit my vocabulary'),
            'type' => MENU_LOCAL_TASK,
        );
    
        return $items;
    }
  • エンティティ(My Vocabulary)の新規作成/更新フォームは通常のFormAPIより作成します(紹介は省略します)
  • エンティティ作成/更新はentity_save()関数で行います
    /**
     * vocabulary submit handler.
     */
    function vocabulary_form_submit($form, &$form_state) {
        // データ入力フォームで埋め込んだエンティティを取得
        $vocabulary = $form_state['my_vocabulary'];
        
         // 新規作成の場合、$vocabularyオブジェクトがない
        if( $vocabulary == null ) $vocabulary= entity_create( "my_vocabulary", array() );
    
        // 入力フォームの値を$vocabularyにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        entity_save( 'my_vocabulary', $vocabulary );
    
        // エンティティの内容の詳細が画面に遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary); // 新規作成の場合にエラー発生
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
  • 更新の場合は問題なくできましたが、新規作成の場合はエラーが発生しました

問題点:エンティティ作成/更新関数(entity_save())が新規作成したエンティティのIDを返さない

  • 上記のエンティティデータ更新関数(entity_save())がデータ更新成功の場合TUREのみ返します
  • hook_entity_info()で定義した「'uri callback' => 'entity_class_uri'」ではエンティティのIDが必要なので、ここでURIの取得はできません
    class MyVocabularyEntity extends Entity{
        // 'label callback' => 'entity_class_label'
        protected function defaultLabel()
        {
            return $this->vocabulary; // vocabulary名を返す
        }
    
        // 'uri callback' => 'entity_class_uri',
        protected function defaultUri()
        {
            return array("path"=>"chinese/vocabularies/".$this->vid); // vocabulary表示URLを返す
        }
    }

解決:データ更新ロジックを「Entity metadata wrappers」にします

  • EntityAPIでは、Entity metadata wrappersが非常に便利な存在です
    • 本家での紹介記事を参考してください
  • 上記のエンティティデータ更新ロジックを以下のように変更
    /**
     * vocabulary submit handler.
     */
    function my_vocabulary_form_submit($form, &$form_state) {
    
        $vocabulary = $form_state['my_vocabulary'];
        if( $vocabulary == null  )  $vocabulary = entity_create('my_vocabulary',array());
    
        // エンティティ入力フォームの値をエンティティにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        // Entity Metadata Wrapper の使用
        $entity = entity_metadata_wrapper('my_vocabulary',  $vocabulary);
        $entity->save();
    
        // 新規作成したエンティティIDをエンティティオブジェクトにセット
        $vocabulary->entity_id = $entity->getIdentifier() ;
    
        // エンティティの詳細画面のURIを取得、遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary );
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
    
  • 「Entity Metadata Wrapper」のデータ更新($entity->save())実行後に、エンティティのIDが返されたので、そのままに取得することができます

「Entity Metadata Wrapper」でIDとラベルの取得方法

  • hook_entity_info()でエンティティの識別キー: IDが定義されています。また画面タイトルとしてよく使用されているラベル(label)も定義されていますが、必須ではありません
  • 「Entity Metadata Wrapper」オブジェクトに変換後に、エンティティIDとラベルの取得方法が通常のような方法ではありません
    「Entity metadata wrappers」オブジェクトのID、ラベルの取得方法
    // Unified way of getting $node->title, $user->name, ...
    // wrapper->label_name ではエラーになります
    $wrapper->label();
    
    // Unified way of getting $node->nid, $user->uid, ...
    // wrapper->id ではエラーになる
    $wrapper->getIdentifier();
  • エンティティのプロパティがprivateで隠していますので、直接に取得はできません
drupal
development
entity type

関数(entity_metadata_wrapper())よりエンティティ(Entity)のデータ更新が簡単にできるようになります

  • ネット上で関数(entity_metadata_wrapper())がよく紹介されています
  • ラップされたエンティティのプロパティ/拡張フィールドのアクセス(set/get)が簡単になりました
  • ラップされたエンティティがデータ更新メソッドも持っています(EntityDrupalWrapper::save())
    • entity_save(), drupal_write_record(), db_insert() db_update() の組み合わせです
      ラップされたエンティティのデータ更新機能はentity_seve(),drupal_write_record(),db_insert(),db_update()の組み合わせ
  • データ保存後に、新規作成の場合はエンティティのIDが返還されなく、自分で取得しなければならない
    • 例:DrupalのEntityAPIでエンティティ新規作成後にIDの取得およびEntityMetadataWrappersの使用

entity_save()がEntityからのオバーライドを呼び出す

  • hook_entity_info()ではEntityクラスの定義をします。
  • ここで、データ更新時のロジックをオバーライドすることができます(例:Entityの更新時刻の設定など)
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MODULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',  // Entityクラスの継承
                 ・・・・・・・・・
            ),
        );
    }
    
    /**
     * hook_entity_info()に定義された'entity class'
     */
    class MyVocabularyEntity extends Entity{
        //  データ更新ロジックのオバーライド
        public function save()
        {
            $this->updated = time() ;   // 更新時刻の設定
            return parent::save();
        }
    
    }

drupal_write_record()が定義されたテーブルスキーマを呼び出し、エンティティの主キーがあるか否かでupdate/insertを決定

  • drupal_write_record()がまずテーブルのスキーマ(モジュールのインストールファイルにあるhook_schema())を呼び出して、テーブルフィールドデータに、エンティティの値をセットします
    • モジュールのインストールファイルにhook_schema()が定義しないと、データ更新はできないようです
    • EntityMetadataWrapperにあるテーブルフィールドを利用していないです。それはdrupa_write_record()がEntityのためのものではなく、ノードタイプなどのデータにも対応しているからです
  • エンティティ(Entity)の主キー(hook_entity_info()で定義したentity::id)がなければdb_insert()で、あればdb_update()データ更新を行います
    //  empty($primary_keys) ? db_insert() : db_update()  
    function drupal_write_record($table, &$record, $primary_keys = array())

 

 

drupal
development
entity type

やりたいこと:エンティティ(Entity)新規作成後に作成したエンティティの詳細画面に遷移

  • hook_entity_info()でエンティティを定義します
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MOUDULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',
                'label callback' => 'entity_class_label', // see MyVocabularyEntity class
                'uri callback' => 'entity_class_uri',      // see MyVocabularyEntity class
                'controller class' => 'MyVocabulryController',
                'base table' => 'my_vocabulary',
                'fieldable' => TRUE,
                'entity keys' => array(
                    'id' => 'entity_id',
                    'label' => 'vocabulary',
                ),
                'bundles' => array(
                    'my_vocabulary' => array(
                        'label'=>'My Vocabulary',
                        'admin' => array(
                            'path' => 'admin/structure/my-vocabulary/manage',
                            'access arguments' => array('administer my vocabulary'),
                            'controller class' => 'EntityDefaultUIController',
                        ),
                    ),
                ),
                'view modes' => array(
                    'full' => array(
                        'label' => t('Default'),
                        'custom settings' => FALSE,
                    ),
                ),
                'module' => 'my_vocabulary',
                'access arguments' => array('administer my vocabulary'),
            ),
    
        );
    }
  • hook_menu()で新規エンティティ作成フォームを定義します
    /**
     * Implements hook_menu().
     */
    function YOUR_MODULE_NAME_menu()
    {
        // for my my vocabulary entity
        $items['my-vocabularies/add'] = array(
            'title' => t('Add Vocabulary'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form') ,
            'access arguments' => array('update my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary'] = array(
            'title' => 'My Vocabulary',
            'page callback' => 'my_vocabulary_page_view',
            'page arguments' => array(2) ,
            'access arguments' => array('view my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary/view'] = array(
            'title' => 'View',
            'type' => MENU_DEFAULT_LOCAL_TASK,  //メニュータブの作成
        );
        $items['my-vocabularies/%my_vocabulary/edit'] = array(
            'title' => t('Edit'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form', 2) ,
            'access arguments' => array('edit my vocabulary'),
            'type' => MENU_LOCAL_TASK,
        );
    
        return $items;
    }
  • エンティティ(My Vocabulary)の新規作成/更新フォームは通常のFormAPIより作成します(紹介は省略します)
  • エンティティ作成/更新はentity_save()関数で行います
    /**
     * vocabulary submit handler.
     */
    function vocabulary_form_submit($form, &$form_state) {
        // データ入力フォームで埋め込んだエンティティを取得
        $vocabulary = $form_state['my_vocabulary'];
        
         // 新規作成の場合、$vocabularyオブジェクトがない
        if( $vocabulary == null ) $vocabulary= entity_create( "my_vocabulary", array() );
    
        // 入力フォームの値を$vocabularyにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        entity_save( 'my_vocabulary', $vocabulary );
    
        // エンティティの内容の詳細が画面に遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary); // 新規作成の場合にエラー発生
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
  • 更新の場合は問題なくできましたが、新規作成の場合はエラーが発生しました

問題点:エンティティ作成/更新関数(entity_save())が新規作成したエンティティのIDを返さない

  • 上記のエンティティデータ更新関数(entity_save())がデータ更新成功の場合TUREのみ返します
  • hook_entity_info()で定義した「'uri callback' => 'entity_class_uri'」ではエンティティのIDが必要なので、ここでURIの取得はできません
    class MyVocabularyEntity extends Entity{
        // 'label callback' => 'entity_class_label'
        protected function defaultLabel()
        {
            return $this->vocabulary; // vocabulary名を返す
        }
    
        // 'uri callback' => 'entity_class_uri',
        protected function defaultUri()
        {
            return array("path"=>"chinese/vocabularies/".$this->vid); // vocabulary表示URLを返す
        }
    }

解決:データ更新ロジックを「Entity metadata wrappers」にします

  • EntityAPIでは、Entity metadata wrappersが非常に便利な存在です
    • 本家での紹介記事を参考してください
  • 上記のエンティティデータ更新ロジックを以下のように変更
    /**
     * vocabulary submit handler.
     */
    function my_vocabulary_form_submit($form, &$form_state) {
    
        $vocabulary = $form_state['my_vocabulary'];
        if( $vocabulary == null  )  $vocabulary = entity_create('my_vocabulary',array());
    
        // エンティティ入力フォームの値をエンティティにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        // Entity Metadata Wrapper の使用
        $entity = entity_metadata_wrapper('my_vocabulary',  $vocabulary);
        $entity->save();
    
        // 新規作成したエンティティIDをエンティティオブジェクトにセット
        $vocabulary->entity_id = $entity->getIdentifier() ;
    
        // エンティティの詳細画面のURIを取得、遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary );
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
    
  • 「Entity Metadata Wrapper」のデータ更新($entity->save())実行後に、エンティティのIDが返されたので、そのままに取得することができます

「Entity Metadata Wrapper」でIDとラベルの取得方法

  • hook_entity_info()でエンティティの識別キー: IDが定義されています。また画面タイトルとしてよく使用されているラベル(label)も定義されていますが、必須ではありません
  • 「Entity Metadata Wrapper」オブジェクトに変換後に、エンティティIDとラベルの取得方法が通常のような方法ではありません
    「Entity metadata wrappers」オブジェクトのID、ラベルの取得方法
    // Unified way of getting $node->title, $user->name, ...
    // wrapper->label_name ではエラーになります
    $wrapper->label();
    
    // Unified way of getting $node->nid, $user->uid, ...
    // wrapper->id ではエラーになる
    $wrapper->getIdentifier();
  • エンティティのプロパティがprivateで隠していますので、直接に取得はできません
drupal
development
entity type

関数(entity_metadata_wrapper())よりエンティティ(Entity)のデータ更新が簡単にできるようになります

  • ネット上で関数(entity_metadata_wrapper())がよく紹介されています
  • ラップされたエンティティのプロパティ/拡張フィールドのアクセス(set/get)が簡単になりました
  • ラップされたエンティティがデータ更新メソッドも持っています(EntityDrupalWrapper::save())
    • entity_save(), drupal_write_record(), db_insert() db_update() の組み合わせです
      ラップされたエンティティのデータ更新機能はentity_seve(),drupal_write_record(),db_insert(),db_update()の組み合わせ
  • データ保存後に、新規作成の場合はエンティティのIDが返還されなく、自分で取得しなければならない
    • 例:DrupalのEntityAPIでエンティティ新規作成後にIDの取得およびEntityMetadataWrappersの使用

entity_save()がEntityからのオバーライドを呼び出す

  • hook_entity_info()ではEntityクラスの定義をします。
  • ここで、データ更新時のロジックをオバーライドすることができます(例:Entityの更新時刻の設定など)
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MODULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',  // Entityクラスの継承
                 ・・・・・・・・・
            ),
        );
    }
    
    /**
     * hook_entity_info()に定義された'entity class'
     */
    class MyVocabularyEntity extends Entity{
        //  データ更新ロジックのオバーライド
        public function save()
        {
            $this->updated = time() ;   // 更新時刻の設定
            return parent::save();
        }
    
    }

drupal_write_record()が定義されたテーブルスキーマを呼び出し、エンティティの主キーがあるか否かでupdate/insertを決定

  • drupal_write_record()がまずテーブルのスキーマ(モジュールのインストールファイルにあるhook_schema())を呼び出して、テーブルフィールドデータに、エンティティの値をセットします
    • モジュールのインストールファイルにhook_schema()が定義しないと、データ更新はできないようです
    • EntityMetadataWrapperにあるテーブルフィールドを利用していないです。それはdrupa_write_record()がEntityのためのものではなく、ノードタイプなどのデータにも対応しているからです
  • エンティティ(Entity)の主キー(hook_entity_info()で定義したentity::id)がなければdb_insert()で、あればdb_update()データ更新を行います
    //  empty($primary_keys) ? db_insert() : db_update()  
    function drupal_write_record($table, &$record, $primary_keys = array())

 

 

drupal
development
entity type

やりたいこと:エンティティ(Entity)新規作成後に作成したエンティティの詳細画面に遷移

  • hook_entity_info()でエンティティを定義します
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MOUDULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',
                'label callback' => 'entity_class_label', // see MyVocabularyEntity class
                'uri callback' => 'entity_class_uri',      // see MyVocabularyEntity class
                'controller class' => 'MyVocabulryController',
                'base table' => 'my_vocabulary',
                'fieldable' => TRUE,
                'entity keys' => array(
                    'id' => 'entity_id',
                    'label' => 'vocabulary',
                ),
                'bundles' => array(
                    'my_vocabulary' => array(
                        'label'=>'My Vocabulary',
                        'admin' => array(
                            'path' => 'admin/structure/my-vocabulary/manage',
                            'access arguments' => array('administer my vocabulary'),
                            'controller class' => 'EntityDefaultUIController',
                        ),
                    ),
                ),
                'view modes' => array(
                    'full' => array(
                        'label' => t('Default'),
                        'custom settings' => FALSE,
                    ),
                ),
                'module' => 'my_vocabulary',
                'access arguments' => array('administer my vocabulary'),
            ),
    
        );
    }
  • hook_menu()で新規エンティティ作成フォームを定義します
    /**
     * Implements hook_menu().
     */
    function YOUR_MODULE_NAME_menu()
    {
        // for my my vocabulary entity
        $items['my-vocabularies/add'] = array(
            'title' => t('Add Vocabulary'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form') ,
            'access arguments' => array('update my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary'] = array(
            'title' => 'My Vocabulary',
            'page callback' => 'my_vocabulary_page_view',
            'page arguments' => array(2) ,
            'access arguments' => array('view my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary/view'] = array(
            'title' => 'View',
            'type' => MENU_DEFAULT_LOCAL_TASK,  //メニュータブの作成
        );
        $items['my-vocabularies/%my_vocabulary/edit'] = array(
            'title' => t('Edit'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form', 2) ,
            'access arguments' => array('edit my vocabulary'),
            'type' => MENU_LOCAL_TASK,
        );
    
        return $items;
    }
  • エンティティ(My Vocabulary)の新規作成/更新フォームは通常のFormAPIより作成します(紹介は省略します)
  • エンティティ作成/更新はentity_save()関数で行います
    /**
     * vocabulary submit handler.
     */
    function vocabulary_form_submit($form, &$form_state) {
        // データ入力フォームで埋め込んだエンティティを取得
        $vocabulary = $form_state['my_vocabulary'];
        
         // 新規作成の場合、$vocabularyオブジェクトがない
        if( $vocabulary == null ) $vocabulary= entity_create( "my_vocabulary", array() );
    
        // 入力フォームの値を$vocabularyにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        entity_save( 'my_vocabulary', $vocabulary );
    
        // エンティティの内容の詳細が画面に遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary); // 新規作成の場合にエラー発生
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
  • 更新の場合は問題なくできましたが、新規作成の場合はエラーが発生しました

問題点:エンティティ作成/更新関数(entity_save())が新規作成したエンティティのIDを返さない

  • 上記のエンティティデータ更新関数(entity_save())がデータ更新成功の場合TUREのみ返します
  • hook_entity_info()で定義した「'uri callback' => 'entity_class_uri'」ではエンティティのIDが必要なので、ここでURIの取得はできません
    class MyVocabularyEntity extends Entity{
        // 'label callback' => 'entity_class_label'
        protected function defaultLabel()
        {
            return $this->vocabulary; // vocabulary名を返す
        }
    
        // 'uri callback' => 'entity_class_uri',
        protected function defaultUri()
        {
            return array("path"=>"chinese/vocabularies/".$this->vid); // vocabulary表示URLを返す
        }
    }

解決:データ更新ロジックを「Entity metadata wrappers」にします

  • EntityAPIでは、Entity metadata wrappersが非常に便利な存在です
    • 本家での紹介記事を参考してください
  • 上記のエンティティデータ更新ロジックを以下のように変更
    /**
     * vocabulary submit handler.
     */
    function my_vocabulary_form_submit($form, &$form_state) {
    
        $vocabulary = $form_state['my_vocabulary'];
        if( $vocabulary == null  )  $vocabulary = entity_create('my_vocabulary',array());
    
        // エンティティ入力フォームの値をエンティティにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        // Entity Metadata Wrapper の使用
        $entity = entity_metadata_wrapper('my_vocabulary',  $vocabulary);
        $entity->save();
    
        // 新規作成したエンティティIDをエンティティオブジェクトにセット
        $vocabulary->entity_id = $entity->getIdentifier() ;
    
        // エンティティの詳細画面のURIを取得、遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary );
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
    
  • 「Entity Metadata Wrapper」のデータ更新($entity->save())実行後に、エンティティのIDが返されたので、そのままに取得することができます

「Entity Metadata Wrapper」でIDとラベルの取得方法

  • hook_entity_info()でエンティティの識別キー: IDが定義されています。また画面タイトルとしてよく使用されているラベル(label)も定義されていますが、必須ではありません
  • 「Entity Metadata Wrapper」オブジェクトに変換後に、エンティティIDとラベルの取得方法が通常のような方法ではありません
    「Entity metadata wrappers」オブジェクトのID、ラベルの取得方法
    // Unified way of getting $node->title, $user->name, ...
    // wrapper->label_name ではエラーになります
    $wrapper->label();
    
    // Unified way of getting $node->nid, $user->uid, ...
    // wrapper->id ではエラーになる
    $wrapper->getIdentifier();
  • エンティティのプロパティがprivateで隠していますので、直接に取得はできません
drupal
development
entity type

関数(entity_metadata_wrapper())よりエンティティ(Entity)のデータ更新が簡単にできるようになります

  • ネット上で関数(entity_metadata_wrapper())がよく紹介されています
  • ラップされたエンティティのプロパティ/拡張フィールドのアクセス(set/get)が簡単になりました
  • ラップされたエンティティがデータ更新メソッドも持っています(EntityDrupalWrapper::save())
    • entity_save(), drupal_write_record(), db_insert() db_update() の組み合わせです
      ラップされたエンティティのデータ更新機能はentity_seve(),drupal_write_record(),db_insert(),db_update()の組み合わせ
  • データ保存後に、新規作成の場合はエンティティのIDが返還されなく、自分で取得しなければならない
    • 例:DrupalのEntityAPIでエンティティ新規作成後にIDの取得およびEntityMetadataWrappersの使用

entity_save()がEntityからのオバーライドを呼び出す

  • hook_entity_info()ではEntityクラスの定義をします。
  • ここで、データ更新時のロジックをオバーライドすることができます(例:Entityの更新時刻の設定など)
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MODULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',  // Entityクラスの継承
                 ・・・・・・・・・
            ),
        );
    }
    
    /**
     * hook_entity_info()に定義された'entity class'
     */
    class MyVocabularyEntity extends Entity{
        //  データ更新ロジックのオバーライド
        public function save()
        {
            $this->updated = time() ;   // 更新時刻の設定
            return parent::save();
        }
    
    }

drupal_write_record()が定義されたテーブルスキーマを呼び出し、エンティティの主キーがあるか否かでupdate/insertを決定

  • drupal_write_record()がまずテーブルのスキーマ(モジュールのインストールファイルにあるhook_schema())を呼び出して、テーブルフィールドデータに、エンティティの値をセットします
    • モジュールのインストールファイルにhook_schema()が定義しないと、データ更新はできないようです
    • EntityMetadataWrapperにあるテーブルフィールドを利用していないです。それはdrupa_write_record()がEntityのためのものではなく、ノードタイプなどのデータにも対応しているからです
  • エンティティ(Entity)の主キー(hook_entity_info()で定義したentity::id)がなければdb_insert()で、あればdb_update()データ更新を行います
    //  empty($primary_keys) ? db_insert() : db_update()  
    function drupal_write_record($table, &$record, $primary_keys = array())

 

 

drupal
development
entity type

やりたいこと:エンティティ(Entity)新規作成後に作成したエンティティの詳細画面に遷移

  • hook_entity_info()でエンティティを定義します
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MOUDULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',
                'label callback' => 'entity_class_label', // see MyVocabularyEntity class
                'uri callback' => 'entity_class_uri',      // see MyVocabularyEntity class
                'controller class' => 'MyVocabulryController',
                'base table' => 'my_vocabulary',
                'fieldable' => TRUE,
                'entity keys' => array(
                    'id' => 'entity_id',
                    'label' => 'vocabulary',
                ),
                'bundles' => array(
                    'my_vocabulary' => array(
                        'label'=>'My Vocabulary',
                        'admin' => array(
                            'path' => 'admin/structure/my-vocabulary/manage',
                            'access arguments' => array('administer my vocabulary'),
                            'controller class' => 'EntityDefaultUIController',
                        ),
                    ),
                ),
                'view modes' => array(
                    'full' => array(
                        'label' => t('Default'),
                        'custom settings' => FALSE,
                    ),
                ),
                'module' => 'my_vocabulary',
                'access arguments' => array('administer my vocabulary'),
            ),
    
        );
    }
  • hook_menu()で新規エンティティ作成フォームを定義します
    /**
     * Implements hook_menu().
     */
    function YOUR_MODULE_NAME_menu()
    {
        // for my my vocabulary entity
        $items['my-vocabularies/add'] = array(
            'title' => t('Add Vocabulary'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form') ,
            'access arguments' => array('update my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary'] = array(
            'title' => 'My Vocabulary',
            'page callback' => 'my_vocabulary_page_view',
            'page arguments' => array(2) ,
            'access arguments' => array('view my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary/view'] = array(
            'title' => 'View',
            'type' => MENU_DEFAULT_LOCAL_TASK,  //メニュータブの作成
        );
        $items['my-vocabularies/%my_vocabulary/edit'] = array(
            'title' => t('Edit'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form', 2) ,
            'access arguments' => array('edit my vocabulary'),
            'type' => MENU_LOCAL_TASK,
        );
    
        return $items;
    }
  • エンティティ(My Vocabulary)の新規作成/更新フォームは通常のFormAPIより作成します(紹介は省略します)
  • エンティティ作成/更新はentity_save()関数で行います
    /**
     * vocabulary submit handler.
     */
    function vocabulary_form_submit($form, &$form_state) {
        // データ入力フォームで埋め込んだエンティティを取得
        $vocabulary = $form_state['my_vocabulary'];
        
         // 新規作成の場合、$vocabularyオブジェクトがない
        if( $vocabulary == null ) $vocabulary= entity_create( "my_vocabulary", array() );
    
        // 入力フォームの値を$vocabularyにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        entity_save( 'my_vocabulary', $vocabulary );
    
        // エンティティの内容の詳細が画面に遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary); // 新規作成の場合にエラー発生
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
  • 更新の場合は問題なくできましたが、新規作成の場合はエラーが発生しました

問題点:エンティティ作成/更新関数(entity_save())が新規作成したエンティティのIDを返さない

  • 上記のエンティティデータ更新関数(entity_save())がデータ更新成功の場合TUREのみ返します
  • hook_entity_info()で定義した「'uri callback' => 'entity_class_uri'」ではエンティティのIDが必要なので、ここでURIの取得はできません
    class MyVocabularyEntity extends Entity{
        // 'label callback' => 'entity_class_label'
        protected function defaultLabel()
        {
            return $this->vocabulary; // vocabulary名を返す
        }
    
        // 'uri callback' => 'entity_class_uri',
        protected function defaultUri()
        {
            return array("path"=>"chinese/vocabularies/".$this->vid); // vocabulary表示URLを返す
        }
    }

解決:データ更新ロジックを「Entity metadata wrappers」にします

  • EntityAPIでは、Entity metadata wrappersが非常に便利な存在です
    • 本家での紹介記事を参考してください
  • 上記のエンティティデータ更新ロジックを以下のように変更
    /**
     * vocabulary submit handler.
     */
    function my_vocabulary_form_submit($form, &$form_state) {
    
        $vocabulary = $form_state['my_vocabulary'];
        if( $vocabulary == null  )  $vocabulary = entity_create('my_vocabulary',array());
    
        // エンティティ入力フォームの値をエンティティにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        // Entity Metadata Wrapper の使用
        $entity = entity_metadata_wrapper('my_vocabulary',  $vocabulary);
        $entity->save();
    
        // 新規作成したエンティティIDをエンティティオブジェクトにセット
        $vocabulary->entity_id = $entity->getIdentifier() ;
    
        // エンティティの詳細画面のURIを取得、遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary );
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
    
  • 「Entity Metadata Wrapper」のデータ更新($entity->save())実行後に、エンティティのIDが返されたので、そのままに取得することができます

「Entity Metadata Wrapper」でIDとラベルの取得方法

  • hook_entity_info()でエンティティの識別キー: IDが定義されています。また画面タイトルとしてよく使用されているラベル(label)も定義されていますが、必須ではありません
  • 「Entity Metadata Wrapper」オブジェクトに変換後に、エンティティIDとラベルの取得方法が通常のような方法ではありません
    「Entity metadata wrappers」オブジェクトのID、ラベルの取得方法
    // Unified way of getting $node->title, $user->name, ...
    // wrapper->label_name ではエラーになります
    $wrapper->label();
    
    // Unified way of getting $node->nid, $user->uid, ...
    // wrapper->id ではエラーになる
    $wrapper->getIdentifier();
  • エンティティのプロパティがprivateで隠していますので、直接に取得はできません
drupal
development
entity type

関数(entity_metadata_wrapper())よりエンティティ(Entity)のデータ更新が簡単にできるようになります

  • ネット上で関数(entity_metadata_wrapper())がよく紹介されています
  • ラップされたエンティティのプロパティ/拡張フィールドのアクセス(set/get)が簡単になりました
  • ラップされたエンティティがデータ更新メソッドも持っています(EntityDrupalWrapper::save())
    • entity_save(), drupal_write_record(), db_insert() db_update() の組み合わせです
      ラップされたエンティティのデータ更新機能はentity_seve(),drupal_write_record(),db_insert(),db_update()の組み合わせ
  • データ保存後に、新規作成の場合はエンティティのIDが返還されなく、自分で取得しなければならない
    • 例:DrupalのEntityAPIでエンティティ新規作成後にIDの取得およびEntityMetadataWrappersの使用

entity_save()がEntityからのオバーライドを呼び出す

  • hook_entity_info()ではEntityクラスの定義をします。
  • ここで、データ更新時のロジックをオバーライドすることができます(例:Entityの更新時刻の設定など)
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MODULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',  // Entityクラスの継承
                 ・・・・・・・・・
            ),
        );
    }
    
    /**
     * hook_entity_info()に定義された'entity class'
     */
    class MyVocabularyEntity extends Entity{
        //  データ更新ロジックのオバーライド
        public function save()
        {
            $this->updated = time() ;   // 更新時刻の設定
            return parent::save();
        }
    
    }

drupal_write_record()が定義されたテーブルスキーマを呼び出し、エンティティの主キーがあるか否かでupdate/insertを決定

  • drupal_write_record()がまずテーブルのスキーマ(モジュールのインストールファイルにあるhook_schema())を呼び出して、テーブルフィールドデータに、エンティティの値をセットします
    • モジュールのインストールファイルにhook_schema()が定義しないと、データ更新はできないようです
    • EntityMetadataWrapperにあるテーブルフィールドを利用していないです。それはdrupa_write_record()がEntityのためのものではなく、ノードタイプなどのデータにも対応しているからです
  • エンティティ(Entity)の主キー(hook_entity_info()で定義したentity::id)がなければdb_insert()で、あればdb_update()データ更新を行います
    //  empty($primary_keys) ? db_insert() : db_update()  
    function drupal_write_record($table, &$record, $primary_keys = array())

 

 

drupal
development
entity type

やりたいこと:エンティティ(Entity)新規作成後に作成したエンティティの詳細画面に遷移

  • hook_entity_info()でエンティティを定義します
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MOUDULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',
                'label callback' => 'entity_class_label', // see MyVocabularyEntity class
                'uri callback' => 'entity_class_uri',      // see MyVocabularyEntity class
                'controller class' => 'MyVocabulryController',
                'base table' => 'my_vocabulary',
                'fieldable' => TRUE,
                'entity keys' => array(
                    'id' => 'entity_id',
                    'label' => 'vocabulary',
                ),
                'bundles' => array(
                    'my_vocabulary' => array(
                        'label'=>'My Vocabulary',
                        'admin' => array(
                            'path' => 'admin/structure/my-vocabulary/manage',
                            'access arguments' => array('administer my vocabulary'),
                            'controller class' => 'EntityDefaultUIController',
                        ),
                    ),
                ),
                'view modes' => array(
                    'full' => array(
                        'label' => t('Default'),
                        'custom settings' => FALSE,
                    ),
                ),
                'module' => 'my_vocabulary',
                'access arguments' => array('administer my vocabulary'),
            ),
    
        );
    }
  • hook_menu()で新規エンティティ作成フォームを定義します
    /**
     * Implements hook_menu().
     */
    function YOUR_MODULE_NAME_menu()
    {
        // for my my vocabulary entity
        $items['my-vocabularies/add'] = array(
            'title' => t('Add Vocabulary'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form') ,
            'access arguments' => array('update my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary'] = array(
            'title' => 'My Vocabulary',
            'page callback' => 'my_vocabulary_page_view',
            'page arguments' => array(2) ,
            'access arguments' => array('view my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary/view'] = array(
            'title' => 'View',
            'type' => MENU_DEFAULT_LOCAL_TASK,  //メニュータブの作成
        );
        $items['my-vocabularies/%my_vocabulary/edit'] = array(
            'title' => t('Edit'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form', 2) ,
            'access arguments' => array('edit my vocabulary'),
            'type' => MENU_LOCAL_TASK,
        );
    
        return $items;
    }
  • エンティティ(My Vocabulary)の新規作成/更新フォームは通常のFormAPIより作成します(紹介は省略します)
  • エンティティ作成/更新はentity_save()関数で行います
    /**
     * vocabulary submit handler.
     */
    function vocabulary_form_submit($form, &$form_state) {
        // データ入力フォームで埋め込んだエンティティを取得
        $vocabulary = $form_state['my_vocabulary'];
        
         // 新規作成の場合、$vocabularyオブジェクトがない
        if( $vocabulary == null ) $vocabulary= entity_create( "my_vocabulary", array() );
    
        // 入力フォームの値を$vocabularyにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        entity_save( 'my_vocabulary', $vocabulary );
    
        // エンティティの内容の詳細が画面に遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary); // 新規作成の場合にエラー発生
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
  • 更新の場合は問題なくできましたが、新規作成の場合はエラーが発生しました

問題点:エンティティ作成/更新関数(entity_save())が新規作成したエンティティのIDを返さない

  • 上記のエンティティデータ更新関数(entity_save())がデータ更新成功の場合TUREのみ返します
  • hook_entity_info()で定義した「'uri callback' => 'entity_class_uri'」ではエンティティのIDが必要なので、ここでURIの取得はできません
    class MyVocabularyEntity extends Entity{
        // 'label callback' => 'entity_class_label'
        protected function defaultLabel()
        {
            return $this->vocabulary; // vocabulary名を返す
        }
    
        // 'uri callback' => 'entity_class_uri',
        protected function defaultUri()
        {
            return array("path"=>"chinese/vocabularies/".$this->vid); // vocabulary表示URLを返す
        }
    }

解決:データ更新ロジックを「Entity metadata wrappers」にします

  • EntityAPIでは、Entity metadata wrappersが非常に便利な存在です
    • 本家での紹介記事を参考してください
  • 上記のエンティティデータ更新ロジックを以下のように変更
    /**
     * vocabulary submit handler.
     */
    function my_vocabulary_form_submit($form, &$form_state) {
    
        $vocabulary = $form_state['my_vocabulary'];
        if( $vocabulary == null  )  $vocabulary = entity_create('my_vocabulary',array());
    
        // エンティティ入力フォームの値をエンティティにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        // Entity Metadata Wrapper の使用
        $entity = entity_metadata_wrapper('my_vocabulary',  $vocabulary);
        $entity->save();
    
        // 新規作成したエンティティIDをエンティティオブジェクトにセット
        $vocabulary->entity_id = $entity->getIdentifier() ;
    
        // エンティティの詳細画面のURIを取得、遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary );
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
    
  • 「Entity Metadata Wrapper」のデータ更新($entity->save())実行後に、エンティティのIDが返されたので、そのままに取得することができます

「Entity Metadata Wrapper」でIDとラベルの取得方法

  • hook_entity_info()でエンティティの識別キー: IDが定義されています。また画面タイトルとしてよく使用されているラベル(label)も定義されていますが、必須ではありません
  • 「Entity Metadata Wrapper」オブジェクトに変換後に、エンティティIDとラベルの取得方法が通常のような方法ではありません
    「Entity metadata wrappers」オブジェクトのID、ラベルの取得方法
    // Unified way of getting $node->title, $user->name, ...
    // wrapper->label_name ではエラーになります
    $wrapper->label();
    
    // Unified way of getting $node->nid, $user->uid, ...
    // wrapper->id ではエラーになる
    $wrapper->getIdentifier();
  • エンティティのプロパティがprivateで隠していますので、直接に取得はできません
drupal
development
entity type

関数(entity_metadata_wrapper())よりエンティティ(Entity)のデータ更新が簡単にできるようになります

  • ネット上で関数(entity_metadata_wrapper())がよく紹介されています
  • ラップされたエンティティのプロパティ/拡張フィールドのアクセス(set/get)が簡単になりました
  • ラップされたエンティティがデータ更新メソッドも持っています(EntityDrupalWrapper::save())
    • entity_save(), drupal_write_record(), db_insert() db_update() の組み合わせです
      ラップされたエンティティのデータ更新機能はentity_seve(),drupal_write_record(),db_insert(),db_update()の組み合わせ
  • データ保存後に、新規作成の場合はエンティティのIDが返還されなく、自分で取得しなければならない
    • 例:DrupalのEntityAPIでエンティティ新規作成後にIDの取得およびEntityMetadataWrappersの使用

entity_save()がEntityからのオバーライドを呼び出す

  • hook_entity_info()ではEntityクラスの定義をします。
  • ここで、データ更新時のロジックをオバーライドすることができます(例:Entityの更新時刻の設定など)
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MODULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',  // Entityクラスの継承
                 ・・・・・・・・・
            ),
        );
    }
    
    /**
     * hook_entity_info()に定義された'entity class'
     */
    class MyVocabularyEntity extends Entity{
        //  データ更新ロジックのオバーライド
        public function save()
        {
            $this->updated = time() ;   // 更新時刻の設定
            return parent::save();
        }
    
    }

drupal_write_record()が定義されたテーブルスキーマを呼び出し、エンティティの主キーがあるか否かでupdate/insertを決定

  • drupal_write_record()がまずテーブルのスキーマ(モジュールのインストールファイルにあるhook_schema())を呼び出して、テーブルフィールドデータに、エンティティの値をセットします
    • モジュールのインストールファイルにhook_schema()が定義しないと、データ更新はできないようです
    • EntityMetadataWrapperにあるテーブルフィールドを利用していないです。それはdrupa_write_record()がEntityのためのものではなく、ノードタイプなどのデータにも対応しているからです
  • エンティティ(Entity)の主キー(hook_entity_info()で定義したentity::id)がなければdb_insert()で、あればdb_update()データ更新を行います
    //  empty($primary_keys) ? db_insert() : db_update()  
    function drupal_write_record($table, &$record, $primary_keys = array())

 

 

drupal
development
entity type

やりたいこと:エンティティ(Entity)新規作成後に作成したエンティティの詳細画面に遷移

  • hook_entity_info()でエンティティを定義します
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MOUDULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',
                'label callback' => 'entity_class_label', // see MyVocabularyEntity class
                'uri callback' => 'entity_class_uri',      // see MyVocabularyEntity class
                'controller class' => 'MyVocabulryController',
                'base table' => 'my_vocabulary',
                'fieldable' => TRUE,
                'entity keys' => array(
                    'id' => 'entity_id',
                    'label' => 'vocabulary',
                ),
                'bundles' => array(
                    'my_vocabulary' => array(
                        'label'=>'My Vocabulary',
                        'admin' => array(
                            'path' => 'admin/structure/my-vocabulary/manage',
                            'access arguments' => array('administer my vocabulary'),
                            'controller class' => 'EntityDefaultUIController',
                        ),
                    ),
                ),
                'view modes' => array(
                    'full' => array(
                        'label' => t('Default'),
                        'custom settings' => FALSE,
                    ),
                ),
                'module' => 'my_vocabulary',
                'access arguments' => array('administer my vocabulary'),
            ),
    
        );
    }
  • hook_menu()で新規エンティティ作成フォームを定義します
    /**
     * Implements hook_menu().
     */
    function YOUR_MODULE_NAME_menu()
    {
        // for my my vocabulary entity
        $items['my-vocabularies/add'] = array(
            'title' => t('Add Vocabulary'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form') ,
            'access arguments' => array('update my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary'] = array(
            'title' => 'My Vocabulary',
            'page callback' => 'my_vocabulary_page_view',
            'page arguments' => array(2) ,
            'access arguments' => array('view my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary/view'] = array(
            'title' => 'View',
            'type' => MENU_DEFAULT_LOCAL_TASK,  //メニュータブの作成
        );
        $items['my-vocabularies/%my_vocabulary/edit'] = array(
            'title' => t('Edit'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form', 2) ,
            'access arguments' => array('edit my vocabulary'),
            'type' => MENU_LOCAL_TASK,
        );
    
        return $items;
    }
  • エンティティ(My Vocabulary)の新規作成/更新フォームは通常のFormAPIより作成します(紹介は省略します)
  • エンティティ作成/更新はentity_save()関数で行います
    /**
     * vocabulary submit handler.
     */
    function vocabulary_form_submit($form, &$form_state) {
        // データ入力フォームで埋め込んだエンティティを取得
        $vocabulary = $form_state['my_vocabulary'];
        
         // 新規作成の場合、$vocabularyオブジェクトがない
        if( $vocabulary == null ) $vocabulary= entity_create( "my_vocabulary", array() );
    
        // 入力フォームの値を$vocabularyにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        entity_save( 'my_vocabulary', $vocabulary );
    
        // エンティティの内容の詳細が画面に遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary); // 新規作成の場合にエラー発生
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
  • 更新の場合は問題なくできましたが、新規作成の場合はエラーが発生しました

問題点:エンティティ作成/更新関数(entity_save())が新規作成したエンティティのIDを返さない

  • 上記のエンティティデータ更新関数(entity_save())がデータ更新成功の場合TUREのみ返します
  • hook_entity_info()で定義した「'uri callback' => 'entity_class_uri'」ではエンティティのIDが必要なので、ここでURIの取得はできません
    class MyVocabularyEntity extends Entity{
        // 'label callback' => 'entity_class_label'
        protected function defaultLabel()
        {
            return $this->vocabulary; // vocabulary名を返す
        }
    
        // 'uri callback' => 'entity_class_uri',
        protected function defaultUri()
        {
            return array("path"=>"chinese/vocabularies/".$this->vid); // vocabulary表示URLを返す
        }
    }

解決:データ更新ロジックを「Entity metadata wrappers」にします

  • EntityAPIでは、Entity metadata wrappersが非常に便利な存在です
    • 本家での紹介記事を参考してください
  • 上記のエンティティデータ更新ロジックを以下のように変更
    /**
     * vocabulary submit handler.
     */
    function my_vocabulary_form_submit($form, &$form_state) {
    
        $vocabulary = $form_state['my_vocabulary'];
        if( $vocabulary == null  )  $vocabulary = entity_create('my_vocabulary',array());
    
        // エンティティ入力フォームの値をエンティティにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        // Entity Metadata Wrapper の使用
        $entity = entity_metadata_wrapper('my_vocabulary',  $vocabulary);
        $entity->save();
    
        // 新規作成したエンティティIDをエンティティオブジェクトにセット
        $vocabulary->entity_id = $entity->getIdentifier() ;
    
        // エンティティの詳細画面のURIを取得、遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary );
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
    
  • 「Entity Metadata Wrapper」のデータ更新($entity->save())実行後に、エンティティのIDが返されたので、そのままに取得することができます

「Entity Metadata Wrapper」でIDとラベルの取得方法

  • hook_entity_info()でエンティティの識別キー: IDが定義されています。また画面タイトルとしてよく使用されているラベル(label)も定義されていますが、必須ではありません
  • 「Entity Metadata Wrapper」オブジェクトに変換後に、エンティティIDとラベルの取得方法が通常のような方法ではありません
    「Entity metadata wrappers」オブジェクトのID、ラベルの取得方法
    // Unified way of getting $node->title, $user->name, ...
    // wrapper->label_name ではエラーになります
    $wrapper->label();
    
    // Unified way of getting $node->nid, $user->uid, ...
    // wrapper->id ではエラーになる
    $wrapper->getIdentifier();
  • エンティティのプロパティがprivateで隠していますので、直接に取得はできません
drupal
development
entity type

関数(entity_metadata_wrapper())よりエンティティ(Entity)のデータ更新が簡単にできるようになります

  • ネット上で関数(entity_metadata_wrapper())がよく紹介されています
  • ラップされたエンティティのプロパティ/拡張フィールドのアクセス(set/get)が簡単になりました
  • ラップされたエンティティがデータ更新メソッドも持っています(EntityDrupalWrapper::save())
    • entity_save(), drupal_write_record(), db_insert() db_update() の組み合わせです
      ラップされたエンティティのデータ更新機能はentity_seve(),drupal_write_record(),db_insert(),db_update()の組み合わせ
  • データ保存後に、新規作成の場合はエンティティのIDが返還されなく、自分で取得しなければならない
    • 例:DrupalのEntityAPIでエンティティ新規作成後にIDの取得およびEntityMetadataWrappersの使用

entity_save()がEntityからのオバーライドを呼び出す

  • hook_entity_info()ではEntityクラスの定義をします。
  • ここで、データ更新時のロジックをオバーライドすることができます(例:Entityの更新時刻の設定など)
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MODULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',  // Entityクラスの継承
                 ・・・・・・・・・
            ),
        );
    }
    
    /**
     * hook_entity_info()に定義された'entity class'
     */
    class MyVocabularyEntity extends Entity{
        //  データ更新ロジックのオバーライド
        public function save()
        {
            $this->updated = time() ;   // 更新時刻の設定
            return parent::save();
        }
    
    }

drupal_write_record()が定義されたテーブルスキーマを呼び出し、エンティティの主キーがあるか否かでupdate/insertを決定

  • drupal_write_record()がまずテーブルのスキーマ(モジュールのインストールファイルにあるhook_schema())を呼び出して、テーブルフィールドデータに、エンティティの値をセットします
    • モジュールのインストールファイルにhook_schema()が定義しないと、データ更新はできないようです
    • EntityMetadataWrapperにあるテーブルフィールドを利用していないです。それはdrupa_write_record()がEntityのためのものではなく、ノードタイプなどのデータにも対応しているからです
  • エンティティ(Entity)の主キー(hook_entity_info()で定義したentity::id)がなければdb_insert()で、あればdb_update()データ更新を行います
    //  empty($primary_keys) ? db_insert() : db_update()  
    function drupal_write_record($table, &$record, $primary_keys = array())

 

 

drupal
development
entity type

やりたいこと:エンティティ(Entity)新規作成後に作成したエンティティの詳細画面に遷移

  • hook_entity_info()でエンティティを定義します
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MOUDULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',
                'label callback' => 'entity_class_label', // see MyVocabularyEntity class
                'uri callback' => 'entity_class_uri',      // see MyVocabularyEntity class
                'controller class' => 'MyVocabulryController',
                'base table' => 'my_vocabulary',
                'fieldable' => TRUE,
                'entity keys' => array(
                    'id' => 'entity_id',
                    'label' => 'vocabulary',
                ),
                'bundles' => array(
                    'my_vocabulary' => array(
                        'label'=>'My Vocabulary',
                        'admin' => array(
                            'path' => 'admin/structure/my-vocabulary/manage',
                            'access arguments' => array('administer my vocabulary'),
                            'controller class' => 'EntityDefaultUIController',
                        ),
                    ),
                ),
                'view modes' => array(
                    'full' => array(
                        'label' => t('Default'),
                        'custom settings' => FALSE,
                    ),
                ),
                'module' => 'my_vocabulary',
                'access arguments' => array('administer my vocabulary'),
            ),
    
        );
    }
  • hook_menu()で新規エンティティ作成フォームを定義します
    /**
     * Implements hook_menu().
     */
    function YOUR_MODULE_NAME_menu()
    {
        // for my my vocabulary entity
        $items['my-vocabularies/add'] = array(
            'title' => t('Add Vocabulary'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form') ,
            'access arguments' => array('update my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary'] = array(
            'title' => 'My Vocabulary',
            'page callback' => 'my_vocabulary_page_view',
            'page arguments' => array(2) ,
            'access arguments' => array('view my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary/view'] = array(
            'title' => 'View',
            'type' => MENU_DEFAULT_LOCAL_TASK,  //メニュータブの作成
        );
        $items['my-vocabularies/%my_vocabulary/edit'] = array(
            'title' => t('Edit'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form', 2) ,
            'access arguments' => array('edit my vocabulary'),
            'type' => MENU_LOCAL_TASK,
        );
    
        return $items;
    }
  • エンティティ(My Vocabulary)の新規作成/更新フォームは通常のFormAPIより作成します(紹介は省略します)
  • エンティティ作成/更新はentity_save()関数で行います
    /**
     * vocabulary submit handler.
     */
    function vocabulary_form_submit($form, &$form_state) {
        // データ入力フォームで埋め込んだエンティティを取得
        $vocabulary = $form_state['my_vocabulary'];
        
         // 新規作成の場合、$vocabularyオブジェクトがない
        if( $vocabulary == null ) $vocabulary= entity_create( "my_vocabulary", array() );
    
        // 入力フォームの値を$vocabularyにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        entity_save( 'my_vocabulary', $vocabulary );
    
        // エンティティの内容の詳細が画面に遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary); // 新規作成の場合にエラー発生
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
  • 更新の場合は問題なくできましたが、新規作成の場合はエラーが発生しました

問題点:エンティティ作成/更新関数(entity_save())が新規作成したエンティティのIDを返さない

  • 上記のエンティティデータ更新関数(entity_save())がデータ更新成功の場合TUREのみ返します
  • hook_entity_info()で定義した「'uri callback' => 'entity_class_uri'」ではエンティティのIDが必要なので、ここでURIの取得はできません
    class MyVocabularyEntity extends Entity{
        // 'label callback' => 'entity_class_label'
        protected function defaultLabel()
        {
            return $this->vocabulary; // vocabulary名を返す
        }
    
        // 'uri callback' => 'entity_class_uri',
        protected function defaultUri()
        {
            return array("path"=>"chinese/vocabularies/".$this->vid); // vocabulary表示URLを返す
        }
    }

解決:データ更新ロジックを「Entity metadata wrappers」にします

  • EntityAPIでは、Entity metadata wrappersが非常に便利な存在です
    • 本家での紹介記事を参考してください
  • 上記のエンティティデータ更新ロジックを以下のように変更
    /**
     * vocabulary submit handler.
     */
    function my_vocabulary_form_submit($form, &$form_state) {
    
        $vocabulary = $form_state['my_vocabulary'];
        if( $vocabulary == null  )  $vocabulary = entity_create('my_vocabulary',array());
    
        // エンティティ入力フォームの値をエンティティにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        // Entity Metadata Wrapper の使用
        $entity = entity_metadata_wrapper('my_vocabulary',  $vocabulary);
        $entity->save();
    
        // 新規作成したエンティティIDをエンティティオブジェクトにセット
        $vocabulary->entity_id = $entity->getIdentifier() ;
    
        // エンティティの詳細画面のURIを取得、遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary );
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
    
  • 「Entity Metadata Wrapper」のデータ更新($entity->save())実行後に、エンティティのIDが返されたので、そのままに取得することができます

「Entity Metadata Wrapper」でIDとラベルの取得方法

  • hook_entity_info()でエンティティの識別キー: IDが定義されています。また画面タイトルとしてよく使用されているラベル(label)も定義されていますが、必須ではありません
  • 「Entity Metadata Wrapper」オブジェクトに変換後に、エンティティIDとラベルの取得方法が通常のような方法ではありません
    「Entity metadata wrappers」オブジェクトのID、ラベルの取得方法
    // Unified way of getting $node->title, $user->name, ...
    // wrapper->label_name ではエラーになります
    $wrapper->label();
    
    // Unified way of getting $node->nid, $user->uid, ...
    // wrapper->id ではエラーになる
    $wrapper->getIdentifier();
  • エンティティのプロパティがprivateで隠していますので、直接に取得はできません
drupal
development
entity type

関数(entity_metadata_wrapper())よりエンティティ(Entity)のデータ更新が簡単にできるようになります

  • ネット上で関数(entity_metadata_wrapper())がよく紹介されています
  • ラップされたエンティティのプロパティ/拡張フィールドのアクセス(set/get)が簡単になりました
  • ラップされたエンティティがデータ更新メソッドも持っています(EntityDrupalWrapper::save())
    • entity_save(), drupal_write_record(), db_insert() db_update() の組み合わせです
      ラップされたエンティティのデータ更新機能はentity_seve(),drupal_write_record(),db_insert(),db_update()の組み合わせ
  • データ保存後に、新規作成の場合はエンティティのIDが返還されなく、自分で取得しなければならない
    • 例:DrupalのEntityAPIでエンティティ新規作成後にIDの取得およびEntityMetadataWrappersの使用

entity_save()がEntityからのオバーライドを呼び出す

  • hook_entity_info()ではEntityクラスの定義をします。
  • ここで、データ更新時のロジックをオバーライドすることができます(例:Entityの更新時刻の設定など)
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MODULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',  // Entityクラスの継承
                 ・・・・・・・・・
            ),
        );
    }
    
    /**
     * hook_entity_info()に定義された'entity class'
     */
    class MyVocabularyEntity extends Entity{
        //  データ更新ロジックのオバーライド
        public function save()
        {
            $this->updated = time() ;   // 更新時刻の設定
            return parent::save();
        }
    
    }

drupal_write_record()が定義されたテーブルスキーマを呼び出し、エンティティの主キーがあるか否かでupdate/insertを決定

  • drupal_write_record()がまずテーブルのスキーマ(モジュールのインストールファイルにあるhook_schema())を呼び出して、テーブルフィールドデータに、エンティティの値をセットします
    • モジュールのインストールファイルにhook_schema()が定義しないと、データ更新はできないようです
    • EntityMetadataWrapperにあるテーブルフィールドを利用していないです。それはdrupa_write_record()がEntityのためのものではなく、ノードタイプなどのデータにも対応しているからです
  • エンティティ(Entity)の主キー(hook_entity_info()で定義したentity::id)がなければdb_insert()で、あればdb_update()データ更新を行います
    //  empty($primary_keys) ? db_insert() : db_update()  
    function drupal_write_record($table, &$record, $primary_keys = array())

 

 

drupal
development
entity type

やりたいこと:エンティティ(Entity)新規作成後に作成したエンティティの詳細画面に遷移

  • hook_entity_info()でエンティティを定義します
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MOUDULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',
                'label callback' => 'entity_class_label', // see MyVocabularyEntity class
                'uri callback' => 'entity_class_uri',      // see MyVocabularyEntity class
                'controller class' => 'MyVocabulryController',
                'base table' => 'my_vocabulary',
                'fieldable' => TRUE,
                'entity keys' => array(
                    'id' => 'entity_id',
                    'label' => 'vocabulary',
                ),
                'bundles' => array(
                    'my_vocabulary' => array(
                        'label'=>'My Vocabulary',
                        'admin' => array(
                            'path' => 'admin/structure/my-vocabulary/manage',
                            'access arguments' => array('administer my vocabulary'),
                            'controller class' => 'EntityDefaultUIController',
                        ),
                    ),
                ),
                'view modes' => array(
                    'full' => array(
                        'label' => t('Default'),
                        'custom settings' => FALSE,
                    ),
                ),
                'module' => 'my_vocabulary',
                'access arguments' => array('administer my vocabulary'),
            ),
    
        );
    }
  • hook_menu()で新規エンティティ作成フォームを定義します
    /**
     * Implements hook_menu().
     */
    function YOUR_MODULE_NAME_menu()
    {
        // for my my vocabulary entity
        $items['my-vocabularies/add'] = array(
            'title' => t('Add Vocabulary'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form') ,
            'access arguments' => array('update my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary'] = array(
            'title' => 'My Vocabulary',
            'page callback' => 'my_vocabulary_page_view',
            'page arguments' => array(2) ,
            'access arguments' => array('view my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary/view'] = array(
            'title' => 'View',
            'type' => MENU_DEFAULT_LOCAL_TASK,  //メニュータブの作成
        );
        $items['my-vocabularies/%my_vocabulary/edit'] = array(
            'title' => t('Edit'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form', 2) ,
            'access arguments' => array('edit my vocabulary'),
            'type' => MENU_LOCAL_TASK,
        );
    
        return $items;
    }
  • エンティティ(My Vocabulary)の新規作成/更新フォームは通常のFormAPIより作成します(紹介は省略します)
  • エンティティ作成/更新はentity_save()関数で行います
    /**
     * vocabulary submit handler.
     */
    function vocabulary_form_submit($form, &$form_state) {
        // データ入力フォームで埋め込んだエンティティを取得
        $vocabulary = $form_state['my_vocabulary'];
        
         // 新規作成の場合、$vocabularyオブジェクトがない
        if( $vocabulary == null ) $vocabulary= entity_create( "my_vocabulary", array() );
    
        // 入力フォームの値を$vocabularyにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        entity_save( 'my_vocabulary', $vocabulary );
    
        // エンティティの内容の詳細が画面に遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary); // 新規作成の場合にエラー発生
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
  • 更新の場合は問題なくできましたが、新規作成の場合はエラーが発生しました

問題点:エンティティ作成/更新関数(entity_save())が新規作成したエンティティのIDを返さない

  • 上記のエンティティデータ更新関数(entity_save())がデータ更新成功の場合TUREのみ返します
  • hook_entity_info()で定義した「'uri callback' => 'entity_class_uri'」ではエンティティのIDが必要なので、ここでURIの取得はできません
    class MyVocabularyEntity extends Entity{
        // 'label callback' => 'entity_class_label'
        protected function defaultLabel()
        {
            return $this->vocabulary; // vocabulary名を返す
        }
    
        // 'uri callback' => 'entity_class_uri',
        protected function defaultUri()
        {
            return array("path"=>"chinese/vocabularies/".$this->vid); // vocabulary表示URLを返す
        }
    }

解決:データ更新ロジックを「Entity metadata wrappers」にします

  • EntityAPIでは、Entity metadata wrappersが非常に便利な存在です
    • 本家での紹介記事を参考してください
  • 上記のエンティティデータ更新ロジックを以下のように変更
    /**
     * vocabulary submit handler.
     */
    function my_vocabulary_form_submit($form, &$form_state) {
    
        $vocabulary = $form_state['my_vocabulary'];
        if( $vocabulary == null  )  $vocabulary = entity_create('my_vocabulary',array());
    
        // エンティティ入力フォームの値をエンティティにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        // Entity Metadata Wrapper の使用
        $entity = entity_metadata_wrapper('my_vocabulary',  $vocabulary);
        $entity->save();
    
        // 新規作成したエンティティIDをエンティティオブジェクトにセット
        $vocabulary->entity_id = $entity->getIdentifier() ;
    
        // エンティティの詳細画面のURIを取得、遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary );
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
    
  • 「Entity Metadata Wrapper」のデータ更新($entity->save())実行後に、エンティティのIDが返されたので、そのままに取得することができます

「Entity Metadata Wrapper」でIDとラベルの取得方法

  • hook_entity_info()でエンティティの識別キー: IDが定義されています。また画面タイトルとしてよく使用されているラベル(label)も定義されていますが、必須ではありません
  • 「Entity Metadata Wrapper」オブジェクトに変換後に、エンティティIDとラベルの取得方法が通常のような方法ではありません
    「Entity metadata wrappers」オブジェクトのID、ラベルの取得方法
    // Unified way of getting $node->title, $user->name, ...
    // wrapper->label_name ではエラーになります
    $wrapper->label();
    
    // Unified way of getting $node->nid, $user->uid, ...
    // wrapper->id ではエラーになる
    $wrapper->getIdentifier();
  • エンティティのプロパティがprivateで隠していますので、直接に取得はできません
drupal
development
entity type

関数(entity_metadata_wrapper())よりエンティティ(Entity)のデータ更新が簡単にできるようになります

  • ネット上で関数(entity_metadata_wrapper())がよく紹介されています
  • ラップされたエンティティのプロパティ/拡張フィールドのアクセス(set/get)が簡単になりました
  • ラップされたエンティティがデータ更新メソッドも持っています(EntityDrupalWrapper::save())
    • entity_save(), drupal_write_record(), db_insert() db_update() の組み合わせです
      ラップされたエンティティのデータ更新機能はentity_seve(),drupal_write_record(),db_insert(),db_update()の組み合わせ
  • データ保存後に、新規作成の場合はエンティティのIDが返還されなく、自分で取得しなければならない
    • 例:DrupalのEntityAPIでエンティティ新規作成後にIDの取得およびEntityMetadataWrappersの使用

entity_save()がEntityからのオバーライドを呼び出す

  • hook_entity_info()ではEntityクラスの定義をします。
  • ここで、データ更新時のロジックをオバーライドすることができます(例:Entityの更新時刻の設定など)
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MODULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',  // Entityクラスの継承
                 ・・・・・・・・・
            ),
        );
    }
    
    /**
     * hook_entity_info()に定義された'entity class'
     */
    class MyVocabularyEntity extends Entity{
        //  データ更新ロジックのオバーライド
        public function save()
        {
            $this->updated = time() ;   // 更新時刻の設定
            return parent::save();
        }
    
    }

drupal_write_record()が定義されたテーブルスキーマを呼び出し、エンティティの主キーがあるか否かでupdate/insertを決定

  • drupal_write_record()がまずテーブルのスキーマ(モジュールのインストールファイルにあるhook_schema())を呼び出して、テーブルフィールドデータに、エンティティの値をセットします
    • モジュールのインストールファイルにhook_schema()が定義しないと、データ更新はできないようです
    • EntityMetadataWrapperにあるテーブルフィールドを利用していないです。それはdrupa_write_record()がEntityのためのものではなく、ノードタイプなどのデータにも対応しているからです
  • エンティティ(Entity)の主キー(hook_entity_info()で定義したentity::id)がなければdb_insert()で、あればdb_update()データ更新を行います
    //  empty($primary_keys) ? db_insert() : db_update()  
    function drupal_write_record($table, &$record, $primary_keys = array())

 

 

drupal
development
entity type

やりたいこと:エンティティ(Entity)新規作成後に作成したエンティティの詳細画面に遷移

  • hook_entity_info()でエンティティを定義します
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MOUDULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',
                'label callback' => 'entity_class_label', // see MyVocabularyEntity class
                'uri callback' => 'entity_class_uri',      // see MyVocabularyEntity class
                'controller class' => 'MyVocabulryController',
                'base table' => 'my_vocabulary',
                'fieldable' => TRUE,
                'entity keys' => array(
                    'id' => 'entity_id',
                    'label' => 'vocabulary',
                ),
                'bundles' => array(
                    'my_vocabulary' => array(
                        'label'=>'My Vocabulary',
                        'admin' => array(
                            'path' => 'admin/structure/my-vocabulary/manage',
                            'access arguments' => array('administer my vocabulary'),
                            'controller class' => 'EntityDefaultUIController',
                        ),
                    ),
                ),
                'view modes' => array(
                    'full' => array(
                        'label' => t('Default'),
                        'custom settings' => FALSE,
                    ),
                ),
                'module' => 'my_vocabulary',
                'access arguments' => array('administer my vocabulary'),
            ),
    
        );
    }
  • hook_menu()で新規エンティティ作成フォームを定義します
    /**
     * Implements hook_menu().
     */
    function YOUR_MODULE_NAME_menu()
    {
        // for my my vocabulary entity
        $items['my-vocabularies/add'] = array(
            'title' => t('Add Vocabulary'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form') ,
            'access arguments' => array('update my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary'] = array(
            'title' => 'My Vocabulary',
            'page callback' => 'my_vocabulary_page_view',
            'page arguments' => array(2) ,
            'access arguments' => array('view my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary/view'] = array(
            'title' => 'View',
            'type' => MENU_DEFAULT_LOCAL_TASK,  //メニュータブの作成
        );
        $items['my-vocabularies/%my_vocabulary/edit'] = array(
            'title' => t('Edit'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form', 2) ,
            'access arguments' => array('edit my vocabulary'),
            'type' => MENU_LOCAL_TASK,
        );
    
        return $items;
    }
  • エンティティ(My Vocabulary)の新規作成/更新フォームは通常のFormAPIより作成します(紹介は省略します)
  • エンティティ作成/更新はentity_save()関数で行います
    /**
     * vocabulary submit handler.
     */
    function vocabulary_form_submit($form, &$form_state) {
        // データ入力フォームで埋め込んだエンティティを取得
        $vocabulary = $form_state['my_vocabulary'];
        
         // 新規作成の場合、$vocabularyオブジェクトがない
        if( $vocabulary == null ) $vocabulary= entity_create( "my_vocabulary", array() );
    
        // 入力フォームの値を$vocabularyにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        entity_save( 'my_vocabulary', $vocabulary );
    
        // エンティティの内容の詳細が画面に遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary); // 新規作成の場合にエラー発生
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
  • 更新の場合は問題なくできましたが、新規作成の場合はエラーが発生しました

問題点:エンティティ作成/更新関数(entity_save())が新規作成したエンティティのIDを返さない

  • 上記のエンティティデータ更新関数(entity_save())がデータ更新成功の場合TUREのみ返します
  • hook_entity_info()で定義した「'uri callback' => 'entity_class_uri'」ではエンティティのIDが必要なので、ここでURIの取得はできません
    class MyVocabularyEntity extends Entity{
        // 'label callback' => 'entity_class_label'
        protected function defaultLabel()
        {
            return $this->vocabulary; // vocabulary名を返す
        }
    
        // 'uri callback' => 'entity_class_uri',
        protected function defaultUri()
        {
            return array("path"=>"chinese/vocabularies/".$this->vid); // vocabulary表示URLを返す
        }
    }

解決:データ更新ロジックを「Entity metadata wrappers」にします

  • EntityAPIでは、Entity metadata wrappersが非常に便利な存在です
    • 本家での紹介記事を参考してください
  • 上記のエンティティデータ更新ロジックを以下のように変更
    /**
     * vocabulary submit handler.
     */
    function my_vocabulary_form_submit($form, &$form_state) {
    
        $vocabulary = $form_state['my_vocabulary'];
        if( $vocabulary == null  )  $vocabulary = entity_create('my_vocabulary',array());
    
        // エンティティ入力フォームの値をエンティティにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        // Entity Metadata Wrapper の使用
        $entity = entity_metadata_wrapper('my_vocabulary',  $vocabulary);
        $entity->save();
    
        // 新規作成したエンティティIDをエンティティオブジェクトにセット
        $vocabulary->entity_id = $entity->getIdentifier() ;
    
        // エンティティの詳細画面のURIを取得、遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary );
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
    
  • 「Entity Metadata Wrapper」のデータ更新($entity->save())実行後に、エンティティのIDが返されたので、そのままに取得することができます

「Entity Metadata Wrapper」でIDとラベルの取得方法

  • hook_entity_info()でエンティティの識別キー: IDが定義されています。また画面タイトルとしてよく使用されているラベル(label)も定義されていますが、必須ではありません
  • 「Entity Metadata Wrapper」オブジェクトに変換後に、エンティティIDとラベルの取得方法が通常のような方法ではありません
    「Entity metadata wrappers」オブジェクトのID、ラベルの取得方法
    // Unified way of getting $node->title, $user->name, ...
    // wrapper->label_name ではエラーになります
    $wrapper->label();
    
    // Unified way of getting $node->nid, $user->uid, ...
    // wrapper->id ではエラーになる
    $wrapper->getIdentifier();
  • エンティティのプロパティがprivateで隠していますので、直接に取得はできません
drupal
development
entity type

関数(entity_metadata_wrapper())よりエンティティ(Entity)のデータ更新が簡単にできるようになります

  • ネット上で関数(entity_metadata_wrapper())がよく紹介されています
  • ラップされたエンティティのプロパティ/拡張フィールドのアクセス(set/get)が簡単になりました
  • ラップされたエンティティがデータ更新メソッドも持っています(EntityDrupalWrapper::save())
    • entity_save(), drupal_write_record(), db_insert() db_update() の組み合わせです
      ラップされたエンティティのデータ更新機能はentity_seve(),drupal_write_record(),db_insert(),db_update()の組み合わせ
  • データ保存後に、新規作成の場合はエンティティのIDが返還されなく、自分で取得しなければならない
    • 例:DrupalのEntityAPIでエンティティ新規作成後にIDの取得およびEntityMetadataWrappersの使用

entity_save()がEntityからのオバーライドを呼び出す

  • hook_entity_info()ではEntityクラスの定義をします。
  • ここで、データ更新時のロジックをオバーライドすることができます(例:Entityの更新時刻の設定など)
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MODULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',  // Entityクラスの継承
                 ・・・・・・・・・
            ),
        );
    }
    
    /**
     * hook_entity_info()に定義された'entity class'
     */
    class MyVocabularyEntity extends Entity{
        //  データ更新ロジックのオバーライド
        public function save()
        {
            $this->updated = time() ;   // 更新時刻の設定
            return parent::save();
        }
    
    }

drupal_write_record()が定義されたテーブルスキーマを呼び出し、エンティティの主キーがあるか否かでupdate/insertを決定

  • drupal_write_record()がまずテーブルのスキーマ(モジュールのインストールファイルにあるhook_schema())を呼び出して、テーブルフィールドデータに、エンティティの値をセットします
    • モジュールのインストールファイルにhook_schema()が定義しないと、データ更新はできないようです
    • EntityMetadataWrapperにあるテーブルフィールドを利用していないです。それはdrupa_write_record()がEntityのためのものではなく、ノードタイプなどのデータにも対応しているからです
  • エンティティ(Entity)の主キー(hook_entity_info()で定義したentity::id)がなければdb_insert()で、あればdb_update()データ更新を行います
    //  empty($primary_keys) ? db_insert() : db_update()  
    function drupal_write_record($table, &$record, $primary_keys = array())

 

 

drupal
development
entity type

やりたいこと:エンティティ(Entity)新規作成後に作成したエンティティの詳細画面に遷移

  • hook_entity_info()でエンティティを定義します
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MOUDULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',
                'label callback' => 'entity_class_label', // see MyVocabularyEntity class
                'uri callback' => 'entity_class_uri',      // see MyVocabularyEntity class
                'controller class' => 'MyVocabulryController',
                'base table' => 'my_vocabulary',
                'fieldable' => TRUE,
                'entity keys' => array(
                    'id' => 'entity_id',
                    'label' => 'vocabulary',
                ),
                'bundles' => array(
                    'my_vocabulary' => array(
                        'label'=>'My Vocabulary',
                        'admin' => array(
                            'path' => 'admin/structure/my-vocabulary/manage',
                            'access arguments' => array('administer my vocabulary'),
                            'controller class' => 'EntityDefaultUIController',
                        ),
                    ),
                ),
                'view modes' => array(
                    'full' => array(
                        'label' => t('Default'),
                        'custom settings' => FALSE,
                    ),
                ),
                'module' => 'my_vocabulary',
                'access arguments' => array('administer my vocabulary'),
            ),
    
        );
    }
  • hook_menu()で新規エンティティ作成フォームを定義します
    /**
     * Implements hook_menu().
     */
    function YOUR_MODULE_NAME_menu()
    {
        // for my my vocabulary entity
        $items['my-vocabularies/add'] = array(
            'title' => t('Add Vocabulary'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form') ,
            'access arguments' => array('update my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary'] = array(
            'title' => 'My Vocabulary',
            'page callback' => 'my_vocabulary_page_view',
            'page arguments' => array(2) ,
            'access arguments' => array('view my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary/view'] = array(
            'title' => 'View',
            'type' => MENU_DEFAULT_LOCAL_TASK,  //メニュータブの作成
        );
        $items['my-vocabularies/%my_vocabulary/edit'] = array(
            'title' => t('Edit'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form', 2) ,
            'access arguments' => array('edit my vocabulary'),
            'type' => MENU_LOCAL_TASK,
        );
    
        return $items;
    }
  • エンティティ(My Vocabulary)の新規作成/更新フォームは通常のFormAPIより作成します(紹介は省略します)
  • エンティティ作成/更新はentity_save()関数で行います
    /**
     * vocabulary submit handler.
     */
    function vocabulary_form_submit($form, &$form_state) {
        // データ入力フォームで埋め込んだエンティティを取得
        $vocabulary = $form_state['my_vocabulary'];
        
         // 新規作成の場合、$vocabularyオブジェクトがない
        if( $vocabulary == null ) $vocabulary= entity_create( "my_vocabulary", array() );
    
        // 入力フォームの値を$vocabularyにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        entity_save( 'my_vocabulary', $vocabulary );
    
        // エンティティの内容の詳細が画面に遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary); // 新規作成の場合にエラー発生
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
  • 更新の場合は問題なくできましたが、新規作成の場合はエラーが発生しました

問題点:エンティティ作成/更新関数(entity_save())が新規作成したエンティティのIDを返さない

  • 上記のエンティティデータ更新関数(entity_save())がデータ更新成功の場合TUREのみ返します
  • hook_entity_info()で定義した「'uri callback' => 'entity_class_uri'」ではエンティティのIDが必要なので、ここでURIの取得はできません
    class MyVocabularyEntity extends Entity{
        // 'label callback' => 'entity_class_label'
        protected function defaultLabel()
        {
            return $this->vocabulary; // vocabulary名を返す
        }
    
        // 'uri callback' => 'entity_class_uri',
        protected function defaultUri()
        {
            return array("path"=>"chinese/vocabularies/".$this->vid); // vocabulary表示URLを返す
        }
    }

解決:データ更新ロジックを「Entity metadata wrappers」にします

  • EntityAPIでは、Entity metadata wrappersが非常に便利な存在です
    • 本家での紹介記事を参考してください
  • 上記のエンティティデータ更新ロジックを以下のように変更
    /**
     * vocabulary submit handler.
     */
    function my_vocabulary_form_submit($form, &$form_state) {
    
        $vocabulary = $form_state['my_vocabulary'];
        if( $vocabulary == null  )  $vocabulary = entity_create('my_vocabulary',array());
    
        // エンティティ入力フォームの値をエンティティにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        // Entity Metadata Wrapper の使用
        $entity = entity_metadata_wrapper('my_vocabulary',  $vocabulary);
        $entity->save();
    
        // 新規作成したエンティティIDをエンティティオブジェクトにセット
        $vocabulary->entity_id = $entity->getIdentifier() ;
    
        // エンティティの詳細画面のURIを取得、遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary );
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
    
  • 「Entity Metadata Wrapper」のデータ更新($entity->save())実行後に、エンティティのIDが返されたので、そのままに取得することができます

「Entity Metadata Wrapper」でIDとラベルの取得方法

  • hook_entity_info()でエンティティの識別キー: IDが定義されています。また画面タイトルとしてよく使用されているラベル(label)も定義されていますが、必須ではありません
  • 「Entity Metadata Wrapper」オブジェクトに変換後に、エンティティIDとラベルの取得方法が通常のような方法ではありません
    「Entity metadata wrappers」オブジェクトのID、ラベルの取得方法
    // Unified way of getting $node->title, $user->name, ...
    // wrapper->label_name ではエラーになります
    $wrapper->label();
    
    // Unified way of getting $node->nid, $user->uid, ...
    // wrapper->id ではエラーになる
    $wrapper->getIdentifier();
  • エンティティのプロパティがprivateで隠していますので、直接に取得はできません
drupal
development
entity type

関数(entity_metadata_wrapper())よりエンティティ(Entity)のデータ更新が簡単にできるようになります

  • ネット上で関数(entity_metadata_wrapper())がよく紹介されています
  • ラップされたエンティティのプロパティ/拡張フィールドのアクセス(set/get)が簡単になりました
  • ラップされたエンティティがデータ更新メソッドも持っています(EntityDrupalWrapper::save())
    • entity_save(), drupal_write_record(), db_insert() db_update() の組み合わせです
      ラップされたエンティティのデータ更新機能はentity_seve(),drupal_write_record(),db_insert(),db_update()の組み合わせ
  • データ保存後に、新規作成の場合はエンティティのIDが返還されなく、自分で取得しなければならない
    • 例:DrupalのEntityAPIでエンティティ新規作成後にIDの取得およびEntityMetadataWrappersの使用

entity_save()がEntityからのオバーライドを呼び出す

  • hook_entity_info()ではEntityクラスの定義をします。
  • ここで、データ更新時のロジックをオバーライドすることができます(例:Entityの更新時刻の設定など)
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MODULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',  // Entityクラスの継承
                 ・・・・・・・・・
            ),
        );
    }
    
    /**
     * hook_entity_info()に定義された'entity class'
     */
    class MyVocabularyEntity extends Entity{
        //  データ更新ロジックのオバーライド
        public function save()
        {
            $this->updated = time() ;   // 更新時刻の設定
            return parent::save();
        }
    
    }

drupal_write_record()が定義されたテーブルスキーマを呼び出し、エンティティの主キーがあるか否かでupdate/insertを決定

  • drupal_write_record()がまずテーブルのスキーマ(モジュールのインストールファイルにあるhook_schema())を呼び出して、テーブルフィールドデータに、エンティティの値をセットします
    • モジュールのインストールファイルにhook_schema()が定義しないと、データ更新はできないようです
    • EntityMetadataWrapperにあるテーブルフィールドを利用していないです。それはdrupa_write_record()がEntityのためのものではなく、ノードタイプなどのデータにも対応しているからです
  • エンティティ(Entity)の主キー(hook_entity_info()で定義したentity::id)がなければdb_insert()で、あればdb_update()データ更新を行います
    //  empty($primary_keys) ? db_insert() : db_update()  
    function drupal_write_record($table, &$record, $primary_keys = array())

 

 

drupal
development
entity type

やりたいこと:エンティティ(Entity)新規作成後に作成したエンティティの詳細画面に遷移

  • hook_entity_info()でエンティティを定義します
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MOUDULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',
                'label callback' => 'entity_class_label', // see MyVocabularyEntity class
                'uri callback' => 'entity_class_uri',      // see MyVocabularyEntity class
                'controller class' => 'MyVocabulryController',
                'base table' => 'my_vocabulary',
                'fieldable' => TRUE,
                'entity keys' => array(
                    'id' => 'entity_id',
                    'label' => 'vocabulary',
                ),
                'bundles' => array(
                    'my_vocabulary' => array(
                        'label'=>'My Vocabulary',
                        'admin' => array(
                            'path' => 'admin/structure/my-vocabulary/manage',
                            'access arguments' => array('administer my vocabulary'),
                            'controller class' => 'EntityDefaultUIController',
                        ),
                    ),
                ),
                'view modes' => array(
                    'full' => array(
                        'label' => t('Default'),
                        'custom settings' => FALSE,
                    ),
                ),
                'module' => 'my_vocabulary',
                'access arguments' => array('administer my vocabulary'),
            ),
    
        );
    }
  • hook_menu()で新規エンティティ作成フォームを定義します
    /**
     * Implements hook_menu().
     */
    function YOUR_MODULE_NAME_menu()
    {
        // for my my vocabulary entity
        $items['my-vocabularies/add'] = array(
            'title' => t('Add Vocabulary'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form') ,
            'access arguments' => array('update my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary'] = array(
            'title' => 'My Vocabulary',
            'page callback' => 'my_vocabulary_page_view',
            'page arguments' => array(2) ,
            'access arguments' => array('view my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary/view'] = array(
            'title' => 'View',
            'type' => MENU_DEFAULT_LOCAL_TASK,  //メニュータブの作成
        );
        $items['my-vocabularies/%my_vocabulary/edit'] = array(
            'title' => t('Edit'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form', 2) ,
            'access arguments' => array('edit my vocabulary'),
            'type' => MENU_LOCAL_TASK,
        );
    
        return $items;
    }
  • エンティティ(My Vocabulary)の新規作成/更新フォームは通常のFormAPIより作成します(紹介は省略します)
  • エンティティ作成/更新はentity_save()関数で行います
    /**
     * vocabulary submit handler.
     */
    function vocabulary_form_submit($form, &$form_state) {
        // データ入力フォームで埋め込んだエンティティを取得
        $vocabulary = $form_state['my_vocabulary'];
        
         // 新規作成の場合、$vocabularyオブジェクトがない
        if( $vocabulary == null ) $vocabulary= entity_create( "my_vocabulary", array() );
    
        // 入力フォームの値を$vocabularyにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        entity_save( 'my_vocabulary', $vocabulary );
    
        // エンティティの内容の詳細が画面に遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary); // 新規作成の場合にエラー発生
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
  • 更新の場合は問題なくできましたが、新規作成の場合はエラーが発生しました

問題点:エンティティ作成/更新関数(entity_save())が新規作成したエンティティのIDを返さない

  • 上記のエンティティデータ更新関数(entity_save())がデータ更新成功の場合TUREのみ返します
  • hook_entity_info()で定義した「'uri callback' => 'entity_class_uri'」ではエンティティのIDが必要なので、ここでURIの取得はできません
    class MyVocabularyEntity extends Entity{
        // 'label callback' => 'entity_class_label'
        protected function defaultLabel()
        {
            return $this->vocabulary; // vocabulary名を返す
        }
    
        // 'uri callback' => 'entity_class_uri',
        protected function defaultUri()
        {
            return array("path"=>"chinese/vocabularies/".$this->vid); // vocabulary表示URLを返す
        }
    }

解決:データ更新ロジックを「Entity metadata wrappers」にします

  • EntityAPIでは、Entity metadata wrappersが非常に便利な存在です
    • 本家での紹介記事を参考してください
  • 上記のエンティティデータ更新ロジックを以下のように変更
    /**
     * vocabulary submit handler.
     */
    function my_vocabulary_form_submit($form, &$form_state) {
    
        $vocabulary = $form_state['my_vocabulary'];
        if( $vocabulary == null  )  $vocabulary = entity_create('my_vocabulary',array());
    
        // エンティティ入力フォームの値をエンティティにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        // Entity Metadata Wrapper の使用
        $entity = entity_metadata_wrapper('my_vocabulary',  $vocabulary);
        $entity->save();
    
        // 新規作成したエンティティIDをエンティティオブジェクトにセット
        $vocabulary->entity_id = $entity->getIdentifier() ;
    
        // エンティティの詳細画面のURIを取得、遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary );
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
    
  • 「Entity Metadata Wrapper」のデータ更新($entity->save())実行後に、エンティティのIDが返されたので、そのままに取得することができます

「Entity Metadata Wrapper」でIDとラベルの取得方法

  • hook_entity_info()でエンティティの識別キー: IDが定義されています。また画面タイトルとしてよく使用されているラベル(label)も定義されていますが、必須ではありません
  • 「Entity Metadata Wrapper」オブジェクトに変換後に、エンティティIDとラベルの取得方法が通常のような方法ではありません
    「Entity metadata wrappers」オブジェクトのID、ラベルの取得方法
    // Unified way of getting $node->title, $user->name, ...
    // wrapper->label_name ではエラーになります
    $wrapper->label();
    
    // Unified way of getting $node->nid, $user->uid, ...
    // wrapper->id ではエラーになる
    $wrapper->getIdentifier();
  • エンティティのプロパティがprivateで隠していますので、直接に取得はできません
drupal
development
entity type

関数(entity_metadata_wrapper())よりエンティティ(Entity)のデータ更新が簡単にできるようになります

  • ネット上で関数(entity_metadata_wrapper())がよく紹介されています
  • ラップされたエンティティのプロパティ/拡張フィールドのアクセス(set/get)が簡単になりました
  • ラップされたエンティティがデータ更新メソッドも持っています(EntityDrupalWrapper::save())
    • entity_save(), drupal_write_record(), db_insert() db_update() の組み合わせです
      ラップされたエンティティのデータ更新機能はentity_seve(),drupal_write_record(),db_insert(),db_update()の組み合わせ
  • データ保存後に、新規作成の場合はエンティティのIDが返還されなく、自分で取得しなければならない
    • 例:DrupalのEntityAPIでエンティティ新規作成後にIDの取得およびEntityMetadataWrappersの使用

entity_save()がEntityからのオバーライドを呼び出す

  • hook_entity_info()ではEntityクラスの定義をします。
  • ここで、データ更新時のロジックをオバーライドすることができます(例:Entityの更新時刻の設定など)
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MODULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',  // Entityクラスの継承
                 ・・・・・・・・・
            ),
        );
    }
    
    /**
     * hook_entity_info()に定義された'entity class'
     */
    class MyVocabularyEntity extends Entity{
        //  データ更新ロジックのオバーライド
        public function save()
        {
            $this->updated = time() ;   // 更新時刻の設定
            return parent::save();
        }
    
    }

drupal_write_record()が定義されたテーブルスキーマを呼び出し、エンティティの主キーがあるか否かでupdate/insertを決定

  • drupal_write_record()がまずテーブルのスキーマ(モジュールのインストールファイルにあるhook_schema())を呼び出して、テーブルフィールドデータに、エンティティの値をセットします
    • モジュールのインストールファイルにhook_schema()が定義しないと、データ更新はできないようです
    • EntityMetadataWrapperにあるテーブルフィールドを利用していないです。それはdrupa_write_record()がEntityのためのものではなく、ノードタイプなどのデータにも対応しているからです
  • エンティティ(Entity)の主キー(hook_entity_info()で定義したentity::id)がなければdb_insert()で、あればdb_update()データ更新を行います
    //  empty($primary_keys) ? db_insert() : db_update()  
    function drupal_write_record($table, &$record, $primary_keys = array())

 

 

drupal
development
entity type

やりたいこと:エンティティ(Entity)新規作成後に作成したエンティティの詳細画面に遷移

  • hook_entity_info()でエンティティを定義します
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MOUDULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',
                'label callback' => 'entity_class_label', // see MyVocabularyEntity class
                'uri callback' => 'entity_class_uri',      // see MyVocabularyEntity class
                'controller class' => 'MyVocabulryController',
                'base table' => 'my_vocabulary',
                'fieldable' => TRUE,
                'entity keys' => array(
                    'id' => 'entity_id',
                    'label' => 'vocabulary',
                ),
                'bundles' => array(
                    'my_vocabulary' => array(
                        'label'=>'My Vocabulary',
                        'admin' => array(
                            'path' => 'admin/structure/my-vocabulary/manage',
                            'access arguments' => array('administer my vocabulary'),
                            'controller class' => 'EntityDefaultUIController',
                        ),
                    ),
                ),
                'view modes' => array(
                    'full' => array(
                        'label' => t('Default'),
                        'custom settings' => FALSE,
                    ),
                ),
                'module' => 'my_vocabulary',
                'access arguments' => array('administer my vocabulary'),
            ),
    
        );
    }
  • hook_menu()で新規エンティティ作成フォームを定義します
    /**
     * Implements hook_menu().
     */
    function YOUR_MODULE_NAME_menu()
    {
        // for my my vocabulary entity
        $items['my-vocabularies/add'] = array(
            'title' => t('Add Vocabulary'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form') ,
            'access arguments' => array('update my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary'] = array(
            'title' => 'My Vocabulary',
            'page callback' => 'my_vocabulary_page_view',
            'page arguments' => array(2) ,
            'access arguments' => array('view my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary/view'] = array(
            'title' => 'View',
            'type' => MENU_DEFAULT_LOCAL_TASK,  //メニュータブの作成
        );
        $items['my-vocabularies/%my_vocabulary/edit'] = array(
            'title' => t('Edit'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form', 2) ,
            'access arguments' => array('edit my vocabulary'),
            'type' => MENU_LOCAL_TASK,
        );
    
        return $items;
    }
  • エンティティ(My Vocabulary)の新規作成/更新フォームは通常のFormAPIより作成します(紹介は省略します)
  • エンティティ作成/更新はentity_save()関数で行います
    /**
     * vocabulary submit handler.
     */
    function vocabulary_form_submit($form, &$form_state) {
        // データ入力フォームで埋め込んだエンティティを取得
        $vocabulary = $form_state['my_vocabulary'];
        
         // 新規作成の場合、$vocabularyオブジェクトがない
        if( $vocabulary == null ) $vocabulary= entity_create( "my_vocabulary", array() );
    
        // 入力フォームの値を$vocabularyにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        entity_save( 'my_vocabulary', $vocabulary );
    
        // エンティティの内容の詳細が画面に遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary); // 新規作成の場合にエラー発生
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
  • 更新の場合は問題なくできましたが、新規作成の場合はエラーが発生しました

問題点:エンティティ作成/更新関数(entity_save())が新規作成したエンティティのIDを返さない

  • 上記のエンティティデータ更新関数(entity_save())がデータ更新成功の場合TUREのみ返します
  • hook_entity_info()で定義した「'uri callback' => 'entity_class_uri'」ではエンティティのIDが必要なので、ここでURIの取得はできません
    class MyVocabularyEntity extends Entity{
        // 'label callback' => 'entity_class_label'
        protected function defaultLabel()
        {
            return $this->vocabulary; // vocabulary名を返す
        }
    
        // 'uri callback' => 'entity_class_uri',
        protected function defaultUri()
        {
            return array("path"=>"chinese/vocabularies/".$this->vid); // vocabulary表示URLを返す
        }
    }

解決:データ更新ロジックを「Entity metadata wrappers」にします

  • EntityAPIでは、Entity metadata wrappersが非常に便利な存在です
    • 本家での紹介記事を参考してください
  • 上記のエンティティデータ更新ロジックを以下のように変更
    /**
     * vocabulary submit handler.
     */
    function my_vocabulary_form_submit($form, &$form_state) {
    
        $vocabulary = $form_state['my_vocabulary'];
        if( $vocabulary == null  )  $vocabulary = entity_create('my_vocabulary',array());
    
        // エンティティ入力フォームの値をエンティティにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        // Entity Metadata Wrapper の使用
        $entity = entity_metadata_wrapper('my_vocabulary',  $vocabulary);
        $entity->save();
    
        // 新規作成したエンティティIDをエンティティオブジェクトにセット
        $vocabulary->entity_id = $entity->getIdentifier() ;
    
        // エンティティの詳細画面のURIを取得、遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary );
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
    
  • 「Entity Metadata Wrapper」のデータ更新($entity->save())実行後に、エンティティのIDが返されたので、そのままに取得することができます

「Entity Metadata Wrapper」でIDとラベルの取得方法

  • hook_entity_info()でエンティティの識別キー: IDが定義されています。また画面タイトルとしてよく使用されているラベル(label)も定義されていますが、必須ではありません
  • 「Entity Metadata Wrapper」オブジェクトに変換後に、エンティティIDとラベルの取得方法が通常のような方法ではありません
    「Entity metadata wrappers」オブジェクトのID、ラベルの取得方法
    // Unified way of getting $node->title, $user->name, ...
    // wrapper->label_name ではエラーになります
    $wrapper->label();
    
    // Unified way of getting $node->nid, $user->uid, ...
    // wrapper->id ではエラーになる
    $wrapper->getIdentifier();
  • エンティティのプロパティがprivateで隠していますので、直接に取得はできません
drupal
development
entity type

関数(entity_metadata_wrapper())よりエンティティ(Entity)のデータ更新が簡単にできるようになります

  • ネット上で関数(entity_metadata_wrapper())がよく紹介されています
  • ラップされたエンティティのプロパティ/拡張フィールドのアクセス(set/get)が簡単になりました
  • ラップされたエンティティがデータ更新メソッドも持っています(EntityDrupalWrapper::save())
    • entity_save(), drupal_write_record(), db_insert() db_update() の組み合わせです
      ラップされたエンティティのデータ更新機能はentity_seve(),drupal_write_record(),db_insert(),db_update()の組み合わせ
  • データ保存後に、新規作成の場合はエンティティのIDが返還されなく、自分で取得しなければならない
    • 例:DrupalのEntityAPIでエンティティ新規作成後にIDの取得およびEntityMetadataWrappersの使用

entity_save()がEntityからのオバーライドを呼び出す

  • hook_entity_info()ではEntityクラスの定義をします。
  • ここで、データ更新時のロジックをオバーライドすることができます(例:Entityの更新時刻の設定など)
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MODULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',  // Entityクラスの継承
                 ・・・・・・・・・
            ),
        );
    }
    
    /**
     * hook_entity_info()に定義された'entity class'
     */
    class MyVocabularyEntity extends Entity{
        //  データ更新ロジックのオバーライド
        public function save()
        {
            $this->updated = time() ;   // 更新時刻の設定
            return parent::save();
        }
    
    }

drupal_write_record()が定義されたテーブルスキーマを呼び出し、エンティティの主キーがあるか否かでupdate/insertを決定

  • drupal_write_record()がまずテーブルのスキーマ(モジュールのインストールファイルにあるhook_schema())を呼び出して、テーブルフィールドデータに、エンティティの値をセットします
    • モジュールのインストールファイルにhook_schema()が定義しないと、データ更新はできないようです
    • EntityMetadataWrapperにあるテーブルフィールドを利用していないです。それはdrupa_write_record()がEntityのためのものではなく、ノードタイプなどのデータにも対応しているからです
  • エンティティ(Entity)の主キー(hook_entity_info()で定義したentity::id)がなければdb_insert()で、あればdb_update()データ更新を行います
    //  empty($primary_keys) ? db_insert() : db_update()  
    function drupal_write_record($table, &$record, $primary_keys = array())

 

 

drupal
development
entity type

やりたいこと:エンティティ(Entity)新規作成後に作成したエンティティの詳細画面に遷移

  • hook_entity_info()でエンティティを定義します
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MOUDULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',
                'label callback' => 'entity_class_label', // see MyVocabularyEntity class
                'uri callback' => 'entity_class_uri',      // see MyVocabularyEntity class
                'controller class' => 'MyVocabulryController',
                'base table' => 'my_vocabulary',
                'fieldable' => TRUE,
                'entity keys' => array(
                    'id' => 'entity_id',
                    'label' => 'vocabulary',
                ),
                'bundles' => array(
                    'my_vocabulary' => array(
                        'label'=>'My Vocabulary',
                        'admin' => array(
                            'path' => 'admin/structure/my-vocabulary/manage',
                            'access arguments' => array('administer my vocabulary'),
                            'controller class' => 'EntityDefaultUIController',
                        ),
                    ),
                ),
                'view modes' => array(
                    'full' => array(
                        'label' => t('Default'),
                        'custom settings' => FALSE,
                    ),
                ),
                'module' => 'my_vocabulary',
                'access arguments' => array('administer my vocabulary'),
            ),
    
        );
    }
  • hook_menu()で新規エンティティ作成フォームを定義します
    /**
     * Implements hook_menu().
     */
    function YOUR_MODULE_NAME_menu()
    {
        // for my my vocabulary entity
        $items['my-vocabularies/add'] = array(
            'title' => t('Add Vocabulary'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form') ,
            'access arguments' => array('update my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary'] = array(
            'title' => 'My Vocabulary',
            'page callback' => 'my_vocabulary_page_view',
            'page arguments' => array(2) ,
            'access arguments' => array('view my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary/view'] = array(
            'title' => 'View',
            'type' => MENU_DEFAULT_LOCAL_TASK,  //メニュータブの作成
        );
        $items['my-vocabularies/%my_vocabulary/edit'] = array(
            'title' => t('Edit'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form', 2) ,
            'access arguments' => array('edit my vocabulary'),
            'type' => MENU_LOCAL_TASK,
        );
    
        return $items;
    }
  • エンティティ(My Vocabulary)の新規作成/更新フォームは通常のFormAPIより作成します(紹介は省略します)
  • エンティティ作成/更新はentity_save()関数で行います
    /**
     * vocabulary submit handler.
     */
    function vocabulary_form_submit($form, &$form_state) {
        // データ入力フォームで埋め込んだエンティティを取得
        $vocabulary = $form_state['my_vocabulary'];
        
         // 新規作成の場合、$vocabularyオブジェクトがない
        if( $vocabulary == null ) $vocabulary= entity_create( "my_vocabulary", array() );
    
        // 入力フォームの値を$vocabularyにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        entity_save( 'my_vocabulary', $vocabulary );
    
        // エンティティの内容の詳細が画面に遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary); // 新規作成の場合にエラー発生
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
  • 更新の場合は問題なくできましたが、新規作成の場合はエラーが発生しました

問題点:エンティティ作成/更新関数(entity_save())が新規作成したエンティティのIDを返さない

  • 上記のエンティティデータ更新関数(entity_save())がデータ更新成功の場合TUREのみ返します
  • hook_entity_info()で定義した「'uri callback' => 'entity_class_uri'」ではエンティティのIDが必要なので、ここでURIの取得はできません
    class MyVocabularyEntity extends Entity{
        // 'label callback' => 'entity_class_label'
        protected function defaultLabel()
        {
            return $this->vocabulary; // vocabulary名を返す
        }
    
        // 'uri callback' => 'entity_class_uri',
        protected function defaultUri()
        {
            return array("path"=>"chinese/vocabularies/".$this->vid); // vocabulary表示URLを返す
        }
    }

解決:データ更新ロジックを「Entity metadata wrappers」にします

  • EntityAPIでは、Entity metadata wrappersが非常に便利な存在です
    • 本家での紹介記事を参考してください
  • 上記のエンティティデータ更新ロジックを以下のように変更
    /**
     * vocabulary submit handler.
     */
    function my_vocabulary_form_submit($form, &$form_state) {
    
        $vocabulary = $form_state['my_vocabulary'];
        if( $vocabulary == null  )  $vocabulary = entity_create('my_vocabulary',array());
    
        // エンティティ入力フォームの値をエンティティにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        // Entity Metadata Wrapper の使用
        $entity = entity_metadata_wrapper('my_vocabulary',  $vocabulary);
        $entity->save();
    
        // 新規作成したエンティティIDをエンティティオブジェクトにセット
        $vocabulary->entity_id = $entity->getIdentifier() ;
    
        // エンティティの詳細画面のURIを取得、遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary );
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
    
  • 「Entity Metadata Wrapper」のデータ更新($entity->save())実行後に、エンティティのIDが返されたので、そのままに取得することができます

「Entity Metadata Wrapper」でIDとラベルの取得方法

  • hook_entity_info()でエンティティの識別キー: IDが定義されています。また画面タイトルとしてよく使用されているラベル(label)も定義されていますが、必須ではありません
  • 「Entity Metadata Wrapper」オブジェクトに変換後に、エンティティIDとラベルの取得方法が通常のような方法ではありません
    「Entity metadata wrappers」オブジェクトのID、ラベルの取得方法
    // Unified way of getting $node->title, $user->name, ...
    // wrapper->label_name ではエラーになります
    $wrapper->label();
    
    // Unified way of getting $node->nid, $user->uid, ...
    // wrapper->id ではエラーになる
    $wrapper->getIdentifier();
  • エンティティのプロパティがprivateで隠していますので、直接に取得はできません
drupal
development
entity type

関数(entity_metadata_wrapper())よりエンティティ(Entity)のデータ更新が簡単にできるようになります

  • ネット上で関数(entity_metadata_wrapper())がよく紹介されています
  • ラップされたエンティティのプロパティ/拡張フィールドのアクセス(set/get)が簡単になりました
  • ラップされたエンティティがデータ更新メソッドも持っています(EntityDrupalWrapper::save())
    • entity_save(), drupal_write_record(), db_insert() db_update() の組み合わせです
      ラップされたエンティティのデータ更新機能はentity_seve(),drupal_write_record(),db_insert(),db_update()の組み合わせ
  • データ保存後に、新規作成の場合はエンティティのIDが返還されなく、自分で取得しなければならない
    • 例:DrupalのEntityAPIでエンティティ新規作成後にIDの取得およびEntityMetadataWrappersの使用

entity_save()がEntityからのオバーライドを呼び出す

  • hook_entity_info()ではEntityクラスの定義をします。
  • ここで、データ更新時のロジックをオバーライドすることができます(例:Entityの更新時刻の設定など)
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MODULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',  // Entityクラスの継承
                 ・・・・・・・・・
            ),
        );
    }
    
    /**
     * hook_entity_info()に定義された'entity class'
     */
    class MyVocabularyEntity extends Entity{
        //  データ更新ロジックのオバーライド
        public function save()
        {
            $this->updated = time() ;   // 更新時刻の設定
            return parent::save();
        }
    
    }

drupal_write_record()が定義されたテーブルスキーマを呼び出し、エンティティの主キーがあるか否かでupdate/insertを決定

  • drupal_write_record()がまずテーブルのスキーマ(モジュールのインストールファイルにあるhook_schema())を呼び出して、テーブルフィールドデータに、エンティティの値をセットします
    • モジュールのインストールファイルにhook_schema()が定義しないと、データ更新はできないようです
    • EntityMetadataWrapperにあるテーブルフィールドを利用していないです。それはdrupa_write_record()がEntityのためのものではなく、ノードタイプなどのデータにも対応しているからです
  • エンティティ(Entity)の主キー(hook_entity_info()で定義したentity::id)がなければdb_insert()で、あればdb_update()データ更新を行います
    //  empty($primary_keys) ? db_insert() : db_update()  
    function drupal_write_record($table, &$record, $primary_keys = array())

 

 

drupal
development
entity type

やりたいこと:エンティティ(Entity)新規作成後に作成したエンティティの詳細画面に遷移

  • hook_entity_info()でエンティティを定義します
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MOUDULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',
                'label callback' => 'entity_class_label', // see MyVocabularyEntity class
                'uri callback' => 'entity_class_uri',      // see MyVocabularyEntity class
                'controller class' => 'MyVocabulryController',
                'base table' => 'my_vocabulary',
                'fieldable' => TRUE,
                'entity keys' => array(
                    'id' => 'entity_id',
                    'label' => 'vocabulary',
                ),
                'bundles' => array(
                    'my_vocabulary' => array(
                        'label'=>'My Vocabulary',
                        'admin' => array(
                            'path' => 'admin/structure/my-vocabulary/manage',
                            'access arguments' => array('administer my vocabulary'),
                            'controller class' => 'EntityDefaultUIController',
                        ),
                    ),
                ),
                'view modes' => array(
                    'full' => array(
                        'label' => t('Default'),
                        'custom settings' => FALSE,
                    ),
                ),
                'module' => 'my_vocabulary',
                'access arguments' => array('administer my vocabulary'),
            ),
    
        );
    }
  • hook_menu()で新規エンティティ作成フォームを定義します
    /**
     * Implements hook_menu().
     */
    function YOUR_MODULE_NAME_menu()
    {
        // for my my vocabulary entity
        $items['my-vocabularies/add'] = array(
            'title' => t('Add Vocabulary'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form') ,
            'access arguments' => array('update my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary'] = array(
            'title' => 'My Vocabulary',
            'page callback' => 'my_vocabulary_page_view',
            'page arguments' => array(2) ,
            'access arguments' => array('view my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary/view'] = array(
            'title' => 'View',
            'type' => MENU_DEFAULT_LOCAL_TASK,  //メニュータブの作成
        );
        $items['my-vocabularies/%my_vocabulary/edit'] = array(
            'title' => t('Edit'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form', 2) ,
            'access arguments' => array('edit my vocabulary'),
            'type' => MENU_LOCAL_TASK,
        );
    
        return $items;
    }
  • エンティティ(My Vocabulary)の新規作成/更新フォームは通常のFormAPIより作成します(紹介は省略します)
  • エンティティ作成/更新はentity_save()関数で行います
    /**
     * vocabulary submit handler.
     */
    function vocabulary_form_submit($form, &$form_state) {
        // データ入力フォームで埋め込んだエンティティを取得
        $vocabulary = $form_state['my_vocabulary'];
        
         // 新規作成の場合、$vocabularyオブジェクトがない
        if( $vocabulary == null ) $vocabulary= entity_create( "my_vocabulary", array() );
    
        // 入力フォームの値を$vocabularyにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        entity_save( 'my_vocabulary', $vocabulary );
    
        // エンティティの内容の詳細が画面に遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary); // 新規作成の場合にエラー発生
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
  • 更新の場合は問題なくできましたが、新規作成の場合はエラーが発生しました

問題点:エンティティ作成/更新関数(entity_save())が新規作成したエンティティのIDを返さない

  • 上記のエンティティデータ更新関数(entity_save())がデータ更新成功の場合TUREのみ返します
  • hook_entity_info()で定義した「'uri callback' => 'entity_class_uri'」ではエンティティのIDが必要なので、ここでURIの取得はできません
    class MyVocabularyEntity extends Entity{
        // 'label callback' => 'entity_class_label'
        protected function defaultLabel()
        {
            return $this->vocabulary; // vocabulary名を返す
        }
    
        // 'uri callback' => 'entity_class_uri',
        protected function defaultUri()
        {
            return array("path"=>"chinese/vocabularies/".$this->vid); // vocabulary表示URLを返す
        }
    }

解決:データ更新ロジックを「Entity metadata wrappers」にします

  • EntityAPIでは、Entity metadata wrappersが非常に便利な存在です
    • 本家での紹介記事を参考してください
  • 上記のエンティティデータ更新ロジックを以下のように変更
    /**
     * vocabulary submit handler.
     */
    function my_vocabulary_form_submit($form, &$form_state) {
    
        $vocabulary = $form_state['my_vocabulary'];
        if( $vocabulary == null  )  $vocabulary = entity_create('my_vocabulary',array());
    
        // エンティティ入力フォームの値をエンティティにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        // Entity Metadata Wrapper の使用
        $entity = entity_metadata_wrapper('my_vocabulary',  $vocabulary);
        $entity->save();
    
        // 新規作成したエンティティIDをエンティティオブジェクトにセット
        $vocabulary->entity_id = $entity->getIdentifier() ;
    
        // エンティティの詳細画面のURIを取得、遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary );
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
    
  • 「Entity Metadata Wrapper」のデータ更新($entity->save())実行後に、エンティティのIDが返されたので、そのままに取得することができます

「Entity Metadata Wrapper」でIDとラベルの取得方法

  • hook_entity_info()でエンティティの識別キー: IDが定義されています。また画面タイトルとしてよく使用されているラベル(label)も定義されていますが、必須ではありません
  • 「Entity Metadata Wrapper」オブジェクトに変換後に、エンティティIDとラベルの取得方法が通常のような方法ではありません
    「Entity metadata wrappers」オブジェクトのID、ラベルの取得方法
    // Unified way of getting $node->title, $user->name, ...
    // wrapper->label_name ではエラーになります
    $wrapper->label();
    
    // Unified way of getting $node->nid, $user->uid, ...
    // wrapper->id ではエラーになる
    $wrapper->getIdentifier();
  • エンティティのプロパティがprivateで隠していますので、直接に取得はできません
drupal
development
entity type

関数(entity_metadata_wrapper())よりエンティティ(Entity)のデータ更新が簡単にできるようになります

  • ネット上で関数(entity_metadata_wrapper())がよく紹介されています
  • ラップされたエンティティのプロパティ/拡張フィールドのアクセス(set/get)が簡単になりました
  • ラップされたエンティティがデータ更新メソッドも持っています(EntityDrupalWrapper::save())
    • entity_save(), drupal_write_record(), db_insert() db_update() の組み合わせです
      ラップされたエンティティのデータ更新機能はentity_seve(),drupal_write_record(),db_insert(),db_update()の組み合わせ
  • データ保存後に、新規作成の場合はエンティティのIDが返還されなく、自分で取得しなければならない
    • 例:DrupalのEntityAPIでエンティティ新規作成後にIDの取得およびEntityMetadataWrappersの使用

entity_save()がEntityからのオバーライドを呼び出す

  • hook_entity_info()ではEntityクラスの定義をします。
  • ここで、データ更新時のロジックをオバーライドすることができます(例:Entityの更新時刻の設定など)
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MODULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',  // Entityクラスの継承
                 ・・・・・・・・・
            ),
        );
    }
    
    /**
     * hook_entity_info()に定義された'entity class'
     */
    class MyVocabularyEntity extends Entity{
        //  データ更新ロジックのオバーライド
        public function save()
        {
            $this->updated = time() ;   // 更新時刻の設定
            return parent::save();
        }
    
    }

drupal_write_record()が定義されたテーブルスキーマを呼び出し、エンティティの主キーがあるか否かでupdate/insertを決定

  • drupal_write_record()がまずテーブルのスキーマ(モジュールのインストールファイルにあるhook_schema())を呼び出して、テーブルフィールドデータに、エンティティの値をセットします
    • モジュールのインストールファイルにhook_schema()が定義しないと、データ更新はできないようです
    • EntityMetadataWrapperにあるテーブルフィールドを利用していないです。それはdrupa_write_record()がEntityのためのものではなく、ノードタイプなどのデータにも対応しているからです
  • エンティティ(Entity)の主キー(hook_entity_info()で定義したentity::id)がなければdb_insert()で、あればdb_update()データ更新を行います
    //  empty($primary_keys) ? db_insert() : db_update()  
    function drupal_write_record($table, &$record, $primary_keys = array())

 

 

drupal
development
entity type

やりたいこと:エンティティ(Entity)新規作成後に作成したエンティティの詳細画面に遷移

  • hook_entity_info()でエンティティを定義します
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MOUDULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',
                'label callback' => 'entity_class_label', // see MyVocabularyEntity class
                'uri callback' => 'entity_class_uri',      // see MyVocabularyEntity class
                'controller class' => 'MyVocabulryController',
                'base table' => 'my_vocabulary',
                'fieldable' => TRUE,
                'entity keys' => array(
                    'id' => 'entity_id',
                    'label' => 'vocabulary',
                ),
                'bundles' => array(
                    'my_vocabulary' => array(
                        'label'=>'My Vocabulary',
                        'admin' => array(
                            'path' => 'admin/structure/my-vocabulary/manage',
                            'access arguments' => array('administer my vocabulary'),
                            'controller class' => 'EntityDefaultUIController',
                        ),
                    ),
                ),
                'view modes' => array(
                    'full' => array(
                        'label' => t('Default'),
                        'custom settings' => FALSE,
                    ),
                ),
                'module' => 'my_vocabulary',
                'access arguments' => array('administer my vocabulary'),
            ),
    
        );
    }
  • hook_menu()で新規エンティティ作成フォームを定義します
    /**
     * Implements hook_menu().
     */
    function YOUR_MODULE_NAME_menu()
    {
        // for my my vocabulary entity
        $items['my-vocabularies/add'] = array(
            'title' => t('Add Vocabulary'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form') ,
            'access arguments' => array('update my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary'] = array(
            'title' => 'My Vocabulary',
            'page callback' => 'my_vocabulary_page_view',
            'page arguments' => array(2) ,
            'access arguments' => array('view my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary/view'] = array(
            'title' => 'View',
            'type' => MENU_DEFAULT_LOCAL_TASK,  //メニュータブの作成
        );
        $items['my-vocabularies/%my_vocabulary/edit'] = array(
            'title' => t('Edit'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form', 2) ,
            'access arguments' => array('edit my vocabulary'),
            'type' => MENU_LOCAL_TASK,
        );
    
        return $items;
    }
  • エンティティ(My Vocabulary)の新規作成/更新フォームは通常のFormAPIより作成します(紹介は省略します)
  • エンティティ作成/更新はentity_save()関数で行います
    /**
     * vocabulary submit handler.
     */
    function vocabulary_form_submit($form, &$form_state) {
        // データ入力フォームで埋め込んだエンティティを取得
        $vocabulary = $form_state['my_vocabulary'];
        
         // 新規作成の場合、$vocabularyオブジェクトがない
        if( $vocabulary == null ) $vocabulary= entity_create( "my_vocabulary", array() );
    
        // 入力フォームの値を$vocabularyにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        entity_save( 'my_vocabulary', $vocabulary );
    
        // エンティティの内容の詳細が画面に遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary); // 新規作成の場合にエラー発生
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
  • 更新の場合は問題なくできましたが、新規作成の場合はエラーが発生しました

問題点:エンティティ作成/更新関数(entity_save())が新規作成したエンティティのIDを返さない

  • 上記のエンティティデータ更新関数(entity_save())がデータ更新成功の場合TUREのみ返します
  • hook_entity_info()で定義した「'uri callback' => 'entity_class_uri'」ではエンティティのIDが必要なので、ここでURIの取得はできません
    class MyVocabularyEntity extends Entity{
        // 'label callback' => 'entity_class_label'
        protected function defaultLabel()
        {
            return $this->vocabulary; // vocabulary名を返す
        }
    
        // 'uri callback' => 'entity_class_uri',
        protected function defaultUri()
        {
            return array("path"=>"chinese/vocabularies/".$this->vid); // vocabulary表示URLを返す
        }
    }

解決:データ更新ロジックを「Entity metadata wrappers」にします

  • EntityAPIでは、Entity metadata wrappersが非常に便利な存在です
    • 本家での紹介記事を参考してください
  • 上記のエンティティデータ更新ロジックを以下のように変更
    /**
     * vocabulary submit handler.
     */
    function my_vocabulary_form_submit($form, &$form_state) {
    
        $vocabulary = $form_state['my_vocabulary'];
        if( $vocabulary == null  )  $vocabulary = entity_create('my_vocabulary',array());
    
        // エンティティ入力フォームの値をエンティティにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        // Entity Metadata Wrapper の使用
        $entity = entity_metadata_wrapper('my_vocabulary',  $vocabulary);
        $entity->save();
    
        // 新規作成したエンティティIDをエンティティオブジェクトにセット
        $vocabulary->entity_id = $entity->getIdentifier() ;
    
        // エンティティの詳細画面のURIを取得、遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary );
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
    
  • 「Entity Metadata Wrapper」のデータ更新($entity->save())実行後に、エンティティのIDが返されたので、そのままに取得することができます

「Entity Metadata Wrapper」でIDとラベルの取得方法

  • hook_entity_info()でエンティティの識別キー: IDが定義されています。また画面タイトルとしてよく使用されているラベル(label)も定義されていますが、必須ではありません
  • 「Entity Metadata Wrapper」オブジェクトに変換後に、エンティティIDとラベルの取得方法が通常のような方法ではありません
    「Entity metadata wrappers」オブジェクトのID、ラベルの取得方法
    // Unified way of getting $node->title, $user->name, ...
    // wrapper->label_name ではエラーになります
    $wrapper->label();
    
    // Unified way of getting $node->nid, $user->uid, ...
    // wrapper->id ではエラーになる
    $wrapper->getIdentifier();
  • エンティティのプロパティがprivateで隠していますので、直接に取得はできません
drupal
development
entity type

関数(entity_metadata_wrapper())よりエンティティ(Entity)のデータ更新が簡単にできるようになります

  • ネット上で関数(entity_metadata_wrapper())がよく紹介されています
  • ラップされたエンティティのプロパティ/拡張フィールドのアクセス(set/get)が簡単になりました
  • ラップされたエンティティがデータ更新メソッドも持っています(EntityDrupalWrapper::save())
    • entity_save(), drupal_write_record(), db_insert() db_update() の組み合わせです
      ラップされたエンティティのデータ更新機能はentity_seve(),drupal_write_record(),db_insert(),db_update()の組み合わせ
  • データ保存後に、新規作成の場合はエンティティのIDが返還されなく、自分で取得しなければならない
    • 例:DrupalのEntityAPIでエンティティ新規作成後にIDの取得およびEntityMetadataWrappersの使用

entity_save()がEntityからのオバーライドを呼び出す

  • hook_entity_info()ではEntityクラスの定義をします。
  • ここで、データ更新時のロジックをオバーライドすることができます(例:Entityの更新時刻の設定など)
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MODULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',  // Entityクラスの継承
                 ・・・・・・・・・
            ),
        );
    }
    
    /**
     * hook_entity_info()に定義された'entity class'
     */
    class MyVocabularyEntity extends Entity{
        //  データ更新ロジックのオバーライド
        public function save()
        {
            $this->updated = time() ;   // 更新時刻の設定
            return parent::save();
        }
    
    }

drupal_write_record()が定義されたテーブルスキーマを呼び出し、エンティティの主キーがあるか否かでupdate/insertを決定

  • drupal_write_record()がまずテーブルのスキーマ(モジュールのインストールファイルにあるhook_schema())を呼び出して、テーブルフィールドデータに、エンティティの値をセットします
    • モジュールのインストールファイルにhook_schema()が定義しないと、データ更新はできないようです
    • EntityMetadataWrapperにあるテーブルフィールドを利用していないです。それはdrupa_write_record()がEntityのためのものではなく、ノードタイプなどのデータにも対応しているからです
  • エンティティ(Entity)の主キー(hook_entity_info()で定義したentity::id)がなければdb_insert()で、あればdb_update()データ更新を行います
    //  empty($primary_keys) ? db_insert() : db_update()  
    function drupal_write_record($table, &$record, $primary_keys = array())

 

 

drupal
development
entity type

やりたいこと:エンティティ(Entity)新規作成後に作成したエンティティの詳細画面に遷移

  • hook_entity_info()でエンティティを定義します
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MOUDULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',
                'label callback' => 'entity_class_label', // see MyVocabularyEntity class
                'uri callback' => 'entity_class_uri',      // see MyVocabularyEntity class
                'controller class' => 'MyVocabulryController',
                'base table' => 'my_vocabulary',
                'fieldable' => TRUE,
                'entity keys' => array(
                    'id' => 'entity_id',
                    'label' => 'vocabulary',
                ),
                'bundles' => array(
                    'my_vocabulary' => array(
                        'label'=>'My Vocabulary',
                        'admin' => array(
                            'path' => 'admin/structure/my-vocabulary/manage',
                            'access arguments' => array('administer my vocabulary'),
                            'controller class' => 'EntityDefaultUIController',
                        ),
                    ),
                ),
                'view modes' => array(
                    'full' => array(
                        'label' => t('Default'),
                        'custom settings' => FALSE,
                    ),
                ),
                'module' => 'my_vocabulary',
                'access arguments' => array('administer my vocabulary'),
            ),
    
        );
    }
  • hook_menu()で新規エンティティ作成フォームを定義します
    /**
     * Implements hook_menu().
     */
    function YOUR_MODULE_NAME_menu()
    {
        // for my my vocabulary entity
        $items['my-vocabularies/add'] = array(
            'title' => t('Add Vocabulary'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form') ,
            'access arguments' => array('update my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary'] = array(
            'title' => 'My Vocabulary',
            'page callback' => 'my_vocabulary_page_view',
            'page arguments' => array(2) ,
            'access arguments' => array('view my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary/view'] = array(
            'title' => 'View',
            'type' => MENU_DEFAULT_LOCAL_TASK,  //メニュータブの作成
        );
        $items['my-vocabularies/%my_vocabulary/edit'] = array(
            'title' => t('Edit'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form', 2) ,
            'access arguments' => array('edit my vocabulary'),
            'type' => MENU_LOCAL_TASK,
        );
    
        return $items;
    }
  • エンティティ(My Vocabulary)の新規作成/更新フォームは通常のFormAPIより作成します(紹介は省略します)
  • エンティティ作成/更新はentity_save()関数で行います
    /**
     * vocabulary submit handler.
     */
    function vocabulary_form_submit($form, &$form_state) {
        // データ入力フォームで埋め込んだエンティティを取得
        $vocabulary = $form_state['my_vocabulary'];
        
         // 新規作成の場合、$vocabularyオブジェクトがない
        if( $vocabulary == null ) $vocabulary= entity_create( "my_vocabulary", array() );
    
        // 入力フォームの値を$vocabularyにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        entity_save( 'my_vocabulary', $vocabulary );
    
        // エンティティの内容の詳細が画面に遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary); // 新規作成の場合にエラー発生
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
  • 更新の場合は問題なくできましたが、新規作成の場合はエラーが発生しました

問題点:エンティティ作成/更新関数(entity_save())が新規作成したエンティティのIDを返さない

  • 上記のエンティティデータ更新関数(entity_save())がデータ更新成功の場合TUREのみ返します
  • hook_entity_info()で定義した「'uri callback' => 'entity_class_uri'」ではエンティティのIDが必要なので、ここでURIの取得はできません
    class MyVocabularyEntity extends Entity{
        // 'label callback' => 'entity_class_label'
        protected function defaultLabel()
        {
            return $this->vocabulary; // vocabulary名を返す
        }
    
        // 'uri callback' => 'entity_class_uri',
        protected function defaultUri()
        {
            return array("path"=>"chinese/vocabularies/".$this->vid); // vocabulary表示URLを返す
        }
    }

解決:データ更新ロジックを「Entity metadata wrappers」にします

  • EntityAPIでは、Entity metadata wrappersが非常に便利な存在です
    • 本家での紹介記事を参考してください
  • 上記のエンティティデータ更新ロジックを以下のように変更
    /**
     * vocabulary submit handler.
     */
    function my_vocabulary_form_submit($form, &$form_state) {
    
        $vocabulary = $form_state['my_vocabulary'];
        if( $vocabulary == null  )  $vocabulary = entity_create('my_vocabulary',array());
    
        // エンティティ入力フォームの値をエンティティにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        // Entity Metadata Wrapper の使用
        $entity = entity_metadata_wrapper('my_vocabulary',  $vocabulary);
        $entity->save();
    
        // 新規作成したエンティティIDをエンティティオブジェクトにセット
        $vocabulary->entity_id = $entity->getIdentifier() ;
    
        // エンティティの詳細画面のURIを取得、遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary );
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
    
  • 「Entity Metadata Wrapper」のデータ更新($entity->save())実行後に、エンティティのIDが返されたので、そのままに取得することができます

「Entity Metadata Wrapper」でIDとラベルの取得方法

  • hook_entity_info()でエンティティの識別キー: IDが定義されています。また画面タイトルとしてよく使用されているラベル(label)も定義されていますが、必須ではありません
  • 「Entity Metadata Wrapper」オブジェクトに変換後に、エンティティIDとラベルの取得方法が通常のような方法ではありません
    「Entity metadata wrappers」オブジェクトのID、ラベルの取得方法
    // Unified way of getting $node->title, $user->name, ...
    // wrapper->label_name ではエラーになります
    $wrapper->label();
    
    // Unified way of getting $node->nid, $user->uid, ...
    // wrapper->id ではエラーになる
    $wrapper->getIdentifier();
  • エンティティのプロパティがprivateで隠していますので、直接に取得はできません
drupal
development
entity type

関数(entity_metadata_wrapper())よりエンティティ(Entity)のデータ更新が簡単にできるようになります

  • ネット上で関数(entity_metadata_wrapper())がよく紹介されています
  • ラップされたエンティティのプロパティ/拡張フィールドのアクセス(set/get)が簡単になりました
  • ラップされたエンティティがデータ更新メソッドも持っています(EntityDrupalWrapper::save())
    • entity_save(), drupal_write_record(), db_insert() db_update() の組み合わせです
      ラップされたエンティティのデータ更新機能はentity_seve(),drupal_write_record(),db_insert(),db_update()の組み合わせ
  • データ保存後に、新規作成の場合はエンティティのIDが返還されなく、自分で取得しなければならない
    • 例:DrupalのEntityAPIでエンティティ新規作成後にIDの取得およびEntityMetadataWrappersの使用

entity_save()がEntityからのオバーライドを呼び出す

  • hook_entity_info()ではEntityクラスの定義をします。
  • ここで、データ更新時のロジックをオバーライドすることができます(例:Entityの更新時刻の設定など)
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MODULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',  // Entityクラスの継承
                 ・・・・・・・・・
            ),
        );
    }
    
    /**
     * hook_entity_info()に定義された'entity class'
     */
    class MyVocabularyEntity extends Entity{
        //  データ更新ロジックのオバーライド
        public function save()
        {
            $this->updated = time() ;   // 更新時刻の設定
            return parent::save();
        }
    
    }

drupal_write_record()が定義されたテーブルスキーマを呼び出し、エンティティの主キーがあるか否かでupdate/insertを決定

  • drupal_write_record()がまずテーブルのスキーマ(モジュールのインストールファイルにあるhook_schema())を呼び出して、テーブルフィールドデータに、エンティティの値をセットします
    • モジュールのインストールファイルにhook_schema()が定義しないと、データ更新はできないようです
    • EntityMetadataWrapperにあるテーブルフィールドを利用していないです。それはdrupa_write_record()がEntityのためのものではなく、ノードタイプなどのデータにも対応しているからです
  • エンティティ(Entity)の主キー(hook_entity_info()で定義したentity::id)がなければdb_insert()で、あればdb_update()データ更新を行います
    //  empty($primary_keys) ? db_insert() : db_update()  
    function drupal_write_record($table, &$record, $primary_keys = array())

 

 

drupal
development
entity type

やりたいこと:エンティティ(Entity)新規作成後に作成したエンティティの詳細画面に遷移

  • hook_entity_info()でエンティティを定義します
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MOUDULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',
                'label callback' => 'entity_class_label', // see MyVocabularyEntity class
                'uri callback' => 'entity_class_uri',      // see MyVocabularyEntity class
                'controller class' => 'MyVocabulryController',
                'base table' => 'my_vocabulary',
                'fieldable' => TRUE,
                'entity keys' => array(
                    'id' => 'entity_id',
                    'label' => 'vocabulary',
                ),
                'bundles' => array(
                    'my_vocabulary' => array(
                        'label'=>'My Vocabulary',
                        'admin' => array(
                            'path' => 'admin/structure/my-vocabulary/manage',
                            'access arguments' => array('administer my vocabulary'),
                            'controller class' => 'EntityDefaultUIController',
                        ),
                    ),
                ),
                'view modes' => array(
                    'full' => array(
                        'label' => t('Default'),
                        'custom settings' => FALSE,
                    ),
                ),
                'module' => 'my_vocabulary',
                'access arguments' => array('administer my vocabulary'),
            ),
    
        );
    }
  • hook_menu()で新規エンティティ作成フォームを定義します
    /**
     * Implements hook_menu().
     */
    function YOUR_MODULE_NAME_menu()
    {
        // for my my vocabulary entity
        $items['my-vocabularies/add'] = array(
            'title' => t('Add Vocabulary'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form') ,
            'access arguments' => array('update my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary'] = array(
            'title' => 'My Vocabulary',
            'page callback' => 'my_vocabulary_page_view',
            'page arguments' => array(2) ,
            'access arguments' => array('view my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary/view'] = array(
            'title' => 'View',
            'type' => MENU_DEFAULT_LOCAL_TASK,  //メニュータブの作成
        );
        $items['my-vocabularies/%my_vocabulary/edit'] = array(
            'title' => t('Edit'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form', 2) ,
            'access arguments' => array('edit my vocabulary'),
            'type' => MENU_LOCAL_TASK,
        );
    
        return $items;
    }
  • エンティティ(My Vocabulary)の新規作成/更新フォームは通常のFormAPIより作成します(紹介は省略します)
  • エンティティ作成/更新はentity_save()関数で行います
    /**
     * vocabulary submit handler.
     */
    function vocabulary_form_submit($form, &$form_state) {
        // データ入力フォームで埋め込んだエンティティを取得
        $vocabulary = $form_state['my_vocabulary'];
        
         // 新規作成の場合、$vocabularyオブジェクトがない
        if( $vocabulary == null ) $vocabulary= entity_create( "my_vocabulary", array() );
    
        // 入力フォームの値を$vocabularyにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        entity_save( 'my_vocabulary', $vocabulary );
    
        // エンティティの内容の詳細が画面に遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary); // 新規作成の場合にエラー発生
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
  • 更新の場合は問題なくできましたが、新規作成の場合はエラーが発生しました

問題点:エンティティ作成/更新関数(entity_save())が新規作成したエンティティのIDを返さない

  • 上記のエンティティデータ更新関数(entity_save())がデータ更新成功の場合TUREのみ返します
  • hook_entity_info()で定義した「'uri callback' => 'entity_class_uri'」ではエンティティのIDが必要なので、ここでURIの取得はできません
    class MyVocabularyEntity extends Entity{
        // 'label callback' => 'entity_class_label'
        protected function defaultLabel()
        {
            return $this->vocabulary; // vocabulary名を返す
        }
    
        // 'uri callback' => 'entity_class_uri',
        protected function defaultUri()
        {
            return array("path"=>"chinese/vocabularies/".$this->vid); // vocabulary表示URLを返す
        }
    }

解決:データ更新ロジックを「Entity metadata wrappers」にします

  • EntityAPIでは、Entity metadata wrappersが非常に便利な存在です
    • 本家での紹介記事を参考してください
  • 上記のエンティティデータ更新ロジックを以下のように変更
    /**
     * vocabulary submit handler.
     */
    function my_vocabulary_form_submit($form, &$form_state) {
    
        $vocabulary = $form_state['my_vocabulary'];
        if( $vocabulary == null  )  $vocabulary = entity_create('my_vocabulary',array());
    
        // エンティティ入力フォームの値をエンティティにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        // Entity Metadata Wrapper の使用
        $entity = entity_metadata_wrapper('my_vocabulary',  $vocabulary);
        $entity->save();
    
        // 新規作成したエンティティIDをエンティティオブジェクトにセット
        $vocabulary->entity_id = $entity->getIdentifier() ;
    
        // エンティティの詳細画面のURIを取得、遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary );
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
    
  • 「Entity Metadata Wrapper」のデータ更新($entity->save())実行後に、エンティティのIDが返されたので、そのままに取得することができます

「Entity Metadata Wrapper」でIDとラベルの取得方法

  • hook_entity_info()でエンティティの識別キー: IDが定義されています。また画面タイトルとしてよく使用されているラベル(label)も定義されていますが、必須ではありません
  • 「Entity Metadata Wrapper」オブジェクトに変換後に、エンティティIDとラベルの取得方法が通常のような方法ではありません
    「Entity metadata wrappers」オブジェクトのID、ラベルの取得方法
    // Unified way of getting $node->title, $user->name, ...
    // wrapper->label_name ではエラーになります
    $wrapper->label();
    
    // Unified way of getting $node->nid, $user->uid, ...
    // wrapper->id ではエラーになる
    $wrapper->getIdentifier();
  • エンティティのプロパティがprivateで隠していますので、直接に取得はできません
drupal
development
entity type

関数(entity_metadata_wrapper())よりエンティティ(Entity)のデータ更新が簡単にできるようになります

  • ネット上で関数(entity_metadata_wrapper())がよく紹介されています
  • ラップされたエンティティのプロパティ/拡張フィールドのアクセス(set/get)が簡単になりました
  • ラップされたエンティティがデータ更新メソッドも持っています(EntityDrupalWrapper::save())
    • entity_save(), drupal_write_record(), db_insert() db_update() の組み合わせです
      ラップされたエンティティのデータ更新機能はentity_seve(),drupal_write_record(),db_insert(),db_update()の組み合わせ
  • データ保存後に、新規作成の場合はエンティティのIDが返還されなく、自分で取得しなければならない
    • 例:DrupalのEntityAPIでエンティティ新規作成後にIDの取得およびEntityMetadataWrappersの使用

entity_save()がEntityからのオバーライドを呼び出す

  • hook_entity_info()ではEntityクラスの定義をします。
  • ここで、データ更新時のロジックをオバーライドすることができます(例:Entityの更新時刻の設定など)
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MODULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',  // Entityクラスの継承
                 ・・・・・・・・・
            ),
        );
    }
    
    /**
     * hook_entity_info()に定義された'entity class'
     */
    class MyVocabularyEntity extends Entity{
        //  データ更新ロジックのオバーライド
        public function save()
        {
            $this->updated = time() ;   // 更新時刻の設定
            return parent::save();
        }
    
    }

drupal_write_record()が定義されたテーブルスキーマを呼び出し、エンティティの主キーがあるか否かでupdate/insertを決定

  • drupal_write_record()がまずテーブルのスキーマ(モジュールのインストールファイルにあるhook_schema())を呼び出して、テーブルフィールドデータに、エンティティの値をセットします
    • モジュールのインストールファイルにhook_schema()が定義しないと、データ更新はできないようです
    • EntityMetadataWrapperにあるテーブルフィールドを利用していないです。それはdrupa_write_record()がEntityのためのものではなく、ノードタイプなどのデータにも対応しているからです
  • エンティティ(Entity)の主キー(hook_entity_info()で定義したentity::id)がなければdb_insert()で、あればdb_update()データ更新を行います
    //  empty($primary_keys) ? db_insert() : db_update()  
    function drupal_write_record($table, &$record, $primary_keys = array())

 

 

drupal
development
entity type

やりたいこと:エンティティ(Entity)新規作成後に作成したエンティティの詳細画面に遷移

  • hook_entity_info()でエンティティを定義します
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MOUDULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',
                'label callback' => 'entity_class_label', // see MyVocabularyEntity class
                'uri callback' => 'entity_class_uri',      // see MyVocabularyEntity class
                'controller class' => 'MyVocabulryController',
                'base table' => 'my_vocabulary',
                'fieldable' => TRUE,
                'entity keys' => array(
                    'id' => 'entity_id',
                    'label' => 'vocabulary',
                ),
                'bundles' => array(
                    'my_vocabulary' => array(
                        'label'=>'My Vocabulary',
                        'admin' => array(
                            'path' => 'admin/structure/my-vocabulary/manage',
                            'access arguments' => array('administer my vocabulary'),
                            'controller class' => 'EntityDefaultUIController',
                        ),
                    ),
                ),
                'view modes' => array(
                    'full' => array(
                        'label' => t('Default'),
                        'custom settings' => FALSE,
                    ),
                ),
                'module' => 'my_vocabulary',
                'access arguments' => array('administer my vocabulary'),
            ),
    
        );
    }
  • hook_menu()で新規エンティティ作成フォームを定義します
    /**
     * Implements hook_menu().
     */
    function YOUR_MODULE_NAME_menu()
    {
        // for my my vocabulary entity
        $items['my-vocabularies/add'] = array(
            'title' => t('Add Vocabulary'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form') ,
            'access arguments' => array('update my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary'] = array(
            'title' => 'My Vocabulary',
            'page callback' => 'my_vocabulary_page_view',
            'page arguments' => array(2) ,
            'access arguments' => array('view my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary/view'] = array(
            'title' => 'View',
            'type' => MENU_DEFAULT_LOCAL_TASK,  //メニュータブの作成
        );
        $items['my-vocabularies/%my_vocabulary/edit'] = array(
            'title' => t('Edit'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form', 2) ,
            'access arguments' => array('edit my vocabulary'),
            'type' => MENU_LOCAL_TASK,
        );
    
        return $items;
    }
  • エンティティ(My Vocabulary)の新規作成/更新フォームは通常のFormAPIより作成します(紹介は省略します)
  • エンティティ作成/更新はentity_save()関数で行います
    /**
     * vocabulary submit handler.
     */
    function vocabulary_form_submit($form, &$form_state) {
        // データ入力フォームで埋め込んだエンティティを取得
        $vocabulary = $form_state['my_vocabulary'];
        
         // 新規作成の場合、$vocabularyオブジェクトがない
        if( $vocabulary == null ) $vocabulary= entity_create( "my_vocabulary", array() );
    
        // 入力フォームの値を$vocabularyにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        entity_save( 'my_vocabulary', $vocabulary );
    
        // エンティティの内容の詳細が画面に遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary); // 新規作成の場合にエラー発生
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
  • 更新の場合は問題なくできましたが、新規作成の場合はエラーが発生しました

問題点:エンティティ作成/更新関数(entity_save())が新規作成したエンティティのIDを返さない

  • 上記のエンティティデータ更新関数(entity_save())がデータ更新成功の場合TUREのみ返します
  • hook_entity_info()で定義した「'uri callback' => 'entity_class_uri'」ではエンティティのIDが必要なので、ここでURIの取得はできません
    class MyVocabularyEntity extends Entity{
        // 'label callback' => 'entity_class_label'
        protected function defaultLabel()
        {
            return $this->vocabulary; // vocabulary名を返す
        }
    
        // 'uri callback' => 'entity_class_uri',
        protected function defaultUri()
        {
            return array("path"=>"chinese/vocabularies/".$this->vid); // vocabulary表示URLを返す
        }
    }

解決:データ更新ロジックを「Entity metadata wrappers」にします

  • EntityAPIでは、Entity metadata wrappersが非常に便利な存在です
    • 本家での紹介記事を参考してください
  • 上記のエンティティデータ更新ロジックを以下のように変更
    /**
     * vocabulary submit handler.
     */
    function my_vocabulary_form_submit($form, &$form_state) {
    
        $vocabulary = $form_state['my_vocabulary'];
        if( $vocabulary == null  )  $vocabulary = entity_create('my_vocabulary',array());
    
        // エンティティ入力フォームの値をエンティティにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        // Entity Metadata Wrapper の使用
        $entity = entity_metadata_wrapper('my_vocabulary',  $vocabulary);
        $entity->save();
    
        // 新規作成したエンティティIDをエンティティオブジェクトにセット
        $vocabulary->entity_id = $entity->getIdentifier() ;
    
        // エンティティの詳細画面のURIを取得、遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary );
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
    
  • 「Entity Metadata Wrapper」のデータ更新($entity->save())実行後に、エンティティのIDが返されたので、そのままに取得することができます

「Entity Metadata Wrapper」でIDとラベルの取得方法

  • hook_entity_info()でエンティティの識別キー: IDが定義されています。また画面タイトルとしてよく使用されているラベル(label)も定義されていますが、必須ではありません
  • 「Entity Metadata Wrapper」オブジェクトに変換後に、エンティティIDとラベルの取得方法が通常のような方法ではありません
    「Entity metadata wrappers」オブジェクトのID、ラベルの取得方法
    // Unified way of getting $node->title, $user->name, ...
    // wrapper->label_name ではエラーになります
    $wrapper->label();
    
    // Unified way of getting $node->nid, $user->uid, ...
    // wrapper->id ではエラーになる
    $wrapper->getIdentifier();
  • エンティティのプロパティがprivateで隠していますので、直接に取得はできません
drupal
development
entity type

関数(entity_metadata_wrapper())よりエンティティ(Entity)のデータ更新が簡単にできるようになります

  • ネット上で関数(entity_metadata_wrapper())がよく紹介されています
  • ラップされたエンティティのプロパティ/拡張フィールドのアクセス(set/get)が簡単になりました
  • ラップされたエンティティがデータ更新メソッドも持っています(EntityDrupalWrapper::save())
    • entity_save(), drupal_write_record(), db_insert() db_update() の組み合わせです
      ラップされたエンティティのデータ更新機能はentity_seve(),drupal_write_record(),db_insert(),db_update()の組み合わせ
  • データ保存後に、新規作成の場合はエンティティのIDが返還されなく、自分で取得しなければならない
    • 例:DrupalのEntityAPIでエンティティ新規作成後にIDの取得およびEntityMetadataWrappersの使用

entity_save()がEntityからのオバーライドを呼び出す

  • hook_entity_info()ではEntityクラスの定義をします。
  • ここで、データ更新時のロジックをオバーライドすることができます(例:Entityの更新時刻の設定など)
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MODULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',  // Entityクラスの継承
                 ・・・・・・・・・
            ),
        );
    }
    
    /**
     * hook_entity_info()に定義された'entity class'
     */
    class MyVocabularyEntity extends Entity{
        //  データ更新ロジックのオバーライド
        public function save()
        {
            $this->updated = time() ;   // 更新時刻の設定
            return parent::save();
        }
    
    }

drupal_write_record()が定義されたテーブルスキーマを呼び出し、エンティティの主キーがあるか否かでupdate/insertを決定

  • drupal_write_record()がまずテーブルのスキーマ(モジュールのインストールファイルにあるhook_schema())を呼び出して、テーブルフィールドデータに、エンティティの値をセットします
    • モジュールのインストールファイルにhook_schema()が定義しないと、データ更新はできないようです
    • EntityMetadataWrapperにあるテーブルフィールドを利用していないです。それはdrupa_write_record()がEntityのためのものではなく、ノードタイプなどのデータにも対応しているからです
  • エンティティ(Entity)の主キー(hook_entity_info()で定義したentity::id)がなければdb_insert()で、あればdb_update()データ更新を行います
    //  empty($primary_keys) ? db_insert() : db_update()  
    function drupal_write_record($table, &$record, $primary_keys = array())

 

 

drupal
development
entity type

やりたいこと:エンティティ(Entity)新規作成後に作成したエンティティの詳細画面に遷移

  • hook_entity_info()でエンティティを定義します
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MOUDULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',
                'label callback' => 'entity_class_label', // see MyVocabularyEntity class
                'uri callback' => 'entity_class_uri',      // see MyVocabularyEntity class
                'controller class' => 'MyVocabulryController',
                'base table' => 'my_vocabulary',
                'fieldable' => TRUE,
                'entity keys' => array(
                    'id' => 'entity_id',
                    'label' => 'vocabulary',
                ),
                'bundles' => array(
                    'my_vocabulary' => array(
                        'label'=>'My Vocabulary',
                        'admin' => array(
                            'path' => 'admin/structure/my-vocabulary/manage',
                            'access arguments' => array('administer my vocabulary'),
                            'controller class' => 'EntityDefaultUIController',
                        ),
                    ),
                ),
                'view modes' => array(
                    'full' => array(
                        'label' => t('Default'),
                        'custom settings' => FALSE,
                    ),
                ),
                'module' => 'my_vocabulary',
                'access arguments' => array('administer my vocabulary'),
            ),
    
        );
    }
  • hook_menu()で新規エンティティ作成フォームを定義します
    /**
     * Implements hook_menu().
     */
    function YOUR_MODULE_NAME_menu()
    {
        // for my my vocabulary entity
        $items['my-vocabularies/add'] = array(
            'title' => t('Add Vocabulary'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form') ,
            'access arguments' => array('update my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary'] = array(
            'title' => 'My Vocabulary',
            'page callback' => 'my_vocabulary_page_view',
            'page arguments' => array(2) ,
            'access arguments' => array('view my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary/view'] = array(
            'title' => 'View',
            'type' => MENU_DEFAULT_LOCAL_TASK,  //メニュータブの作成
        );
        $items['my-vocabularies/%my_vocabulary/edit'] = array(
            'title' => t('Edit'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form', 2) ,
            'access arguments' => array('edit my vocabulary'),
            'type' => MENU_LOCAL_TASK,
        );
    
        return $items;
    }
  • エンティティ(My Vocabulary)の新規作成/更新フォームは通常のFormAPIより作成します(紹介は省略します)
  • エンティティ作成/更新はentity_save()関数で行います
    /**
     * vocabulary submit handler.
     */
    function vocabulary_form_submit($form, &$form_state) {
        // データ入力フォームで埋め込んだエンティティを取得
        $vocabulary = $form_state['my_vocabulary'];
        
         // 新規作成の場合、$vocabularyオブジェクトがない
        if( $vocabulary == null ) $vocabulary= entity_create( "my_vocabulary", array() );
    
        // 入力フォームの値を$vocabularyにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        entity_save( 'my_vocabulary', $vocabulary );
    
        // エンティティの内容の詳細が画面に遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary); // 新規作成の場合にエラー発生
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
  • 更新の場合は問題なくできましたが、新規作成の場合はエラーが発生しました

問題点:エンティティ作成/更新関数(entity_save())が新規作成したエンティティのIDを返さない

  • 上記のエンティティデータ更新関数(entity_save())がデータ更新成功の場合TUREのみ返します
  • hook_entity_info()で定義した「'uri callback' => 'entity_class_uri'」ではエンティティのIDが必要なので、ここでURIの取得はできません
    class MyVocabularyEntity extends Entity{
        // 'label callback' => 'entity_class_label'
        protected function defaultLabel()
        {
            return $this->vocabulary; // vocabulary名を返す
        }
    
        // 'uri callback' => 'entity_class_uri',
        protected function defaultUri()
        {
            return array("path"=>"chinese/vocabularies/".$this->vid); // vocabulary表示URLを返す
        }
    }

解決:データ更新ロジックを「Entity metadata wrappers」にします

  • EntityAPIでは、Entity metadata wrappersが非常に便利な存在です
    • 本家での紹介記事を参考してください
  • 上記のエンティティデータ更新ロジックを以下のように変更
    /**
     * vocabulary submit handler.
     */
    function my_vocabulary_form_submit($form, &$form_state) {
    
        $vocabulary = $form_state['my_vocabulary'];
        if( $vocabulary == null  )  $vocabulary = entity_create('my_vocabulary',array());
    
        // エンティティ入力フォームの値をエンティティにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        // Entity Metadata Wrapper の使用
        $entity = entity_metadata_wrapper('my_vocabulary',  $vocabulary);
        $entity->save();
    
        // 新規作成したエンティティIDをエンティティオブジェクトにセット
        $vocabulary->entity_id = $entity->getIdentifier() ;
    
        // エンティティの詳細画面のURIを取得、遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary );
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
    
  • 「Entity Metadata Wrapper」のデータ更新($entity->save())実行後に、エンティティのIDが返されたので、そのままに取得することができます

「Entity Metadata Wrapper」でIDとラベルの取得方法

  • hook_entity_info()でエンティティの識別キー: IDが定義されています。また画面タイトルとしてよく使用されているラベル(label)も定義されていますが、必須ではありません
  • 「Entity Metadata Wrapper」オブジェクトに変換後に、エンティティIDとラベルの取得方法が通常のような方法ではありません
    「Entity metadata wrappers」オブジェクトのID、ラベルの取得方法
    // Unified way of getting $node->title, $user->name, ...
    // wrapper->label_name ではエラーになります
    $wrapper->label();
    
    // Unified way of getting $node->nid, $user->uid, ...
    // wrapper->id ではエラーになる
    $wrapper->getIdentifier();
  • エンティティのプロパティがprivateで隠していますので、直接に取得はできません
drupal
development
entity type

関数(entity_metadata_wrapper())よりエンティティ(Entity)のデータ更新が簡単にできるようになります

  • ネット上で関数(entity_metadata_wrapper())がよく紹介されています
  • ラップされたエンティティのプロパティ/拡張フィールドのアクセス(set/get)が簡単になりました
  • ラップされたエンティティがデータ更新メソッドも持っています(EntityDrupalWrapper::save())
    • entity_save(), drupal_write_record(), db_insert() db_update() の組み合わせです
      ラップされたエンティティのデータ更新機能はentity_seve(),drupal_write_record(),db_insert(),db_update()の組み合わせ
  • データ保存後に、新規作成の場合はエンティティのIDが返還されなく、自分で取得しなければならない
    • 例:DrupalのEntityAPIでエンティティ新規作成後にIDの取得およびEntityMetadataWrappersの使用

entity_save()がEntityからのオバーライドを呼び出す

  • hook_entity_info()ではEntityクラスの定義をします。
  • ここで、データ更新時のロジックをオバーライドすることができます(例:Entityの更新時刻の設定など)
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MODULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',  // Entityクラスの継承
                 ・・・・・・・・・
            ),
        );
    }
    
    /**
     * hook_entity_info()に定義された'entity class'
     */
    class MyVocabularyEntity extends Entity{
        //  データ更新ロジックのオバーライド
        public function save()
        {
            $this->updated = time() ;   // 更新時刻の設定
            return parent::save();
        }
    
    }

drupal_write_record()が定義されたテーブルスキーマを呼び出し、エンティティの主キーがあるか否かでupdate/insertを決定

  • drupal_write_record()がまずテーブルのスキーマ(モジュールのインストールファイルにあるhook_schema())を呼び出して、テーブルフィールドデータに、エンティティの値をセットします
    • モジュールのインストールファイルにhook_schema()が定義しないと、データ更新はできないようです
    • EntityMetadataWrapperにあるテーブルフィールドを利用していないです。それはdrupa_write_record()がEntityのためのものではなく、ノードタイプなどのデータにも対応しているからです
  • エンティティ(Entity)の主キー(hook_entity_info()で定義したentity::id)がなければdb_insert()で、あればdb_update()データ更新を行います
    //  empty($primary_keys) ? db_insert() : db_update()  
    function drupal_write_record($table, &$record, $primary_keys = array())

 

 

drupal
development
entity type

やりたいこと:エンティティ(Entity)新規作成後に作成したエンティティの詳細画面に遷移

  • hook_entity_info()でエンティティを定義します
    /**
     * Implements hook_entity_info().
     */
    function YOUR_MOUDULE_NAME_entity_info()
    {
        return array(
            'my_vocabulary' => array(
                'label' => t('My Vocabulary'),
                'entity class' => 'MyVocabularyEntity',
                'label callback' => 'entity_class_label', // see MyVocabularyEntity class
                'uri callback' => 'entity_class_uri',      // see MyVocabularyEntity class
                'controller class' => 'MyVocabulryController',
                'base table' => 'my_vocabulary',
                'fieldable' => TRUE,
                'entity keys' => array(
                    'id' => 'entity_id',
                    'label' => 'vocabulary',
                ),
                'bundles' => array(
                    'my_vocabulary' => array(
                        'label'=>'My Vocabulary',
                        'admin' => array(
                            'path' => 'admin/structure/my-vocabulary/manage',
                            'access arguments' => array('administer my vocabulary'),
                            'controller class' => 'EntityDefaultUIController',
                        ),
                    ),
                ),
                'view modes' => array(
                    'full' => array(
                        'label' => t('Default'),
                        'custom settings' => FALSE,
                    ),
                ),
                'module' => 'my_vocabulary',
                'access arguments' => array('administer my vocabulary'),
            ),
    
        );
    }
  • hook_menu()で新規エンティティ作成フォームを定義します
    /**
     * Implements hook_menu().
     */
    function YOUR_MODULE_NAME_menu()
    {
        // for my my vocabulary entity
        $items['my-vocabularies/add'] = array(
            'title' => t('Add Vocabulary'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form') ,
            'access arguments' => array('update my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary'] = array(
            'title' => 'My Vocabulary',
            'page callback' => 'my_vocabulary_page_view',
            'page arguments' => array(2) ,
            'access arguments' => array('view my vocabulary'),
        );
        $items['my-vocabularies/%my_vocabulary/view'] = array(
            'title' => 'View',
            'type' => MENU_DEFAULT_LOCAL_TASK,  //メニュータブの作成
        );
        $items['my-vocabularies/%my_vocabulary/edit'] = array(
            'title' => t('Edit'),
            'page callback' => 'drupal_get_form',
            'page arguments' => array('my_vocabulary_form', 2) ,
            'access arguments' => array('edit my vocabulary'),
            'type' => MENU_LOCAL_TASK,
        );
    
        return $items;
    }
  • エンティティ(My Vocabulary)の新規作成/更新フォームは通常のFormAPIより作成します(紹介は省略します)
  • エンティティ作成/更新はentity_save()関数で行います
    /**
     * vocabulary submit handler.
     */
    function vocabulary_form_submit($form, &$form_state) {
        // データ入力フォームで埋め込んだエンティティを取得
        $vocabulary = $form_state['my_vocabulary'];
        
         // 新規作成の場合、$vocabularyオブジェクトがない
        if( $vocabulary == null ) $vocabulary= entity_create( "my_vocabulary", array() );
    
        // 入力フォームの値を$vocabularyにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        entity_save( 'my_vocabulary', $vocabulary );
    
        // エンティティの内容の詳細が画面に遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary); // 新規作成の場合にエラー発生
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
  • 更新の場合は問題なくできましたが、新規作成の場合はエラーが発生しました

問題点:エンティティ作成/更新関数(entity_save())が新規作成したエンティティのIDを返さない

  • 上記のエンティティデータ更新関数(entity_save())がデータ更新成功の場合TUREのみ返します
  • hook_entity_info()で定義した「'uri callback' => 'entity_class_uri'」ではエンティティのIDが必要なので、ここでURIの取得はできません
    class MyVocabularyEntity extends Entity{
        // 'label callback' => 'entity_class_label'
        protected function defaultLabel()
        {
            return $this->vocabulary; // vocabulary名を返す
        }
    
        // 'uri callback' => 'entity_class_uri',
        protected function defaultUri()
        {
            return array("path"=>"chinese/vocabularies/".$this->vid); // vocabulary表示URLを返す
        }
    }

解決:データ更新ロジックを「Entity metadata wrappers」にします

  • EntityAPIでは、Entity metadata wrappersが非常に便利な存在です
    • 本家での紹介記事を参考してください
  • 上記のエンティティデータ更新ロジックを以下のように変更
    /**
     * vocabulary submit handler.
     */
    function my_vocabulary_form_submit($form, &$form_state) {
    
        $vocabulary = $form_state['my_vocabulary'];
        if( $vocabulary == null  )  $vocabulary = entity_create('my_vocabulary',array());
    
        // エンティティ入力フォームの値をエンティティにセット
        entity_form_submit_build_entity('my_vocabulary', $vocabulary, $form, $form_state);
        // Entity Metadata Wrapper の使用
        $entity = entity_metadata_wrapper('my_vocabulary',  $vocabulary);
        $entity->save();
    
        // 新規作成したエンティティIDをエンティティオブジェクトにセット
        $vocabulary->entity_id = $entity->getIdentifier() ;
    
        // エンティティの詳細画面のURIを取得、遷移
        $vocabulary_uri = entity_uri('my_vocabulary', $vocabulary );
        $form_state['redirect'] = $vocabulary_uri['path'];
    
    }
    
  • 「Entity Metadata Wrapper」のデータ更新($entity->save())実行後に、エンティティのIDが返されたので、そのままに取得することができます

「Entity Metadata Wrapper」でIDとラベルの取得方法

  • hook_entity_info()でエンティティの識別キー: IDが定義されています。また画面タイトルとしてよく使用されているラベル(label)も定義されていますが、必須ではありません
  • 「Entity Metadata Wrapper」オブジェクトに変換後に、エンティティIDとラベルの取得方法が通常のような方法ではありません
    「Entity metadata wrappers」オブジェクトのID、ラベルの取得方法
    // Unified way of getting $node->title, $user->name, ...
    // wrapper->label_name ではエラーになります
    $wrapper->label();
    
    // Unified way of getting $node->nid, $user->uid, ...
    // wrapper->id ではエラーになる
    $wrapper->getIdentifier();
  • エンティティのプロパティがprivateで隠していますので、直接に取得はできません
ホーム

古松

検索

Article Category

  • apache(7)
  • css(19)
  • drupal(295)
  • Electron(4)
  • html(34)
  • javascript(27)
  • laravel(4)
  • linux(5)
  • macOS(2)
  • mysql(13)
  • php(19)
  • python(4)
  • SEO(12)
  • video(72)
  • Visual Studio Code(4)
  • windows(13)
  • wordpress(32)