エントリーフォーム – 複数のエントリーとエントリータイプ&ペアレント

私はプロジェクトのMVPを構築していますが、私はCraftを使用しています。

  1. 実験を作成する(/ experiments /)
  2. 以前作成した実験内の動物用の複数のかごを作成します。 5ケージ – (/実験/ケージ/)
  3. 複数の檻に複数のげっ歯類を追加します。それぞれ5頭のげっ歯類で5頭のケージを作ってください。 (/実験/ケージ/)
  4. 体重/腫瘍サイズ(/実験/ケージ/)などの特定のマウスに測定値を追加する

私はこれがエントリーフォームを使って、このような構造にエントリを追加することで可能になると考えていました。

--Experiments
----Cage 1
------Rodent 1
------Rodent 2
------Rodent 3
----Cage 2
------Rodent 1
------Rodent 2
------Rodent 3
...

私の質問は –

  1. フォームごとに複数のエントリを作成することは可能ですか?
    1つのエントリーフォームの提出書類から5頭の齧歯類を5頭ずつ作成します。

  2. 入力フォームに入力タイプを割り当てることはできますか? (例:CageまたはMouseの入力タイプ?)

  3. 入力フォームを使用して親にエントリを割り当てることはできますか?

これらがエントリーフォーム+構造では不可能な場合、それに近づく最善の方法は何でしょうか?

ありがとう!

ベストアンサー

遅いですが、ここはそうです。

  1. Go to https://pluginfactory.io/ and create a plugin, you
    need at least 1 Controller but you can leave the Name value blank
    to create a controller with the same Name as your PluginHandle. So
    if you choose “Experiment” as your Pluginhandle your controller
    will be ExperimentController
  2. Click on “Build my Plugin” and save the files in your
    craft/plugins/>>pluginhandle<< folder (of
    course you need to create the >>pluginhandle<<
    directory eg.) Then you should install the plugin
  3. Insert this function in your controller. Note: this is just an
    example. I don’t know your fieldLayout or some special behaviors
    you might want to include. So this is just the basic logic with
    some error handling. Important please read the
    commands and change the entryType Ids

         /**
         * @var    bool|array Allows anonymous access to this controller's actions.
         * @access protected
         */
        protected $allowAnonymous = true;
    
        /**
         * @throws Exception
         */
        public function actionSaveEntry(){
            $this->requirePostRequest();
           //check for an Id if there is one we update an existing entry if not we create a new one
            if($entryId = craft()->request->getParam('entryId')){
                if(!$entry = craft()->elements->getElementById($entryId)){
                    throw new Exception('Could not find entry with id');
                }
            }else{
                $entry = new EntryModel();
                $entry->typeId = craft()->request->getParam('entryType');
                $entry->sectionId = craft()->request->getParam('sectionId');
            }
    
           //set the content of your entry/experiment
            $entryData = craft()->request->getParam('experiment');
            $entry->getContent()->setAttributes($entryData['fields']);
    
           //try to save the entry
            if(craft()->entries->saveEntry($entry)){
               //fetch the id from the experiment so we can use that as a parentId for the cage
                $entryId = $entry->id;
               //if everything is alright we can save the cage like we did it with the experiment
                if($cagesData = craft()->request->getParam('cage')){
    
                    foreach ($cagesData as $cageData){
                       //like with the entry check for an Id
                        if($cageId = $cageData['entryId']){
                            if(!$cage = craft()->elements->getElementById($cageId)){
                                throw new Exception('Could not find cage with the given Id');
                            }
                        }else{
                            $cage = new EntryModel();
                            $cage->typeId = 5;//you could as well create a hidden field like for the entry itself but you must change the typeId to your entryType Id
                            $cage->sectionId = craft()->request->getParam('sectionId');
                        }
    
                       //save the content as well
                        $cage->getContent()->setAttributes($cageData['fields']);
                       //and set the parent
                        $cage->parentId = $entryId;
                        if(craft()->entries->saveEntry($cage)){
                            $cageId = $cage->id;
                           //and now we are going to do the same with the animals
                            if($rodentsData = $cageData['rodents']) {
                                $rodentErrors = [];
                                foreach ($rodentsData as $rodentData){
                                   //like with the entry check for an Id
                                    if (array_key_exists('entryId', $rodentData) && $rodentId = $rodentData['entryId']) {
                                        if (!$rodent = craft()->elements->getElementById($rodentId)) {
                                            throw new Exception('Could not find rodent with the given Id');
                                        }
                                    } else {
                                        $rodent = new EntryModel();
                                        $rodent->typeId = 6;//change your entryType Id here
                                        $rodent->sectionId = craft()->request->getParam('sectionId');
                                    }
    
                                    $rodent->getContent()->setAttributes($rodentData['fields']);
                                    $rodent->parentId = $cageId;
                                    if (!craft()->entries->saveEntry($rodent)) {
                                       //important note: if there are any errors here, the cage and the experiment is
                                       //saved anyway so you should insert the id of the experiment to the form in order
                                       //to update the form instead of creating a new one again and again
                                       //if the experiment has an Id but the cage/rodent not you'll just update the experiment
                                       //and create new cages/rodents for it
                                        $rodentErrors[] = $rodent->getErrors();
                                    }else{
                                        $rodentErrors = [];
                                    }
                                }
                               //include errors of each item
                                craft()->urlManager->setRouteVariables(array(
                                    'rodentErrors' => $rodentErrors
                                ));
                            }
                        }else{
                            craft()->urlManager->setRouteVariables(array(
                                'cageErrors' => $cage->getErrors()
                            ));
                        }
                    }
    
                }
            }else{
               //handle your errors here.. you can use $entry->getErrors()
               //return them to your frontend and render them in twig or something
                craft()->urlManager->setRouteVariables(array(
                    'experimentErrors' => $entry->getErrors()
                ));
            }
        }
    
  4. Your html template. Note I don’t know your fieldLayout so I just
    included the title and the craft default body field.
    In order to add your custom fields to the html you need to set the
    input name to entryType[fields][fieldHandle] so if you
    want to add a field with the handle foo to the
    cage you would name it cage[fields][foo].
    As for the routing: your action must be
    pluginHandle/functionName

    <form method="post" accept-charset="UTF-8">
        {{ getCsrfInput() }}
        {# your plugin name and function name #}
        <input type="hidden" name="action" value="test/saveEntry">
        {# the id of your section for me its 4 you need to change this value to your section Id #}
        <input type="hidden" name="sectionId" value="4">
        {# enable the entry #}
        <input type="hidden" name="enabled" value="1">
        {# id of your entry leave it blank to insert a new entry, insert a id to change an existing entry#}
        <input type="hidden" name="entryId" value="">
        {# the id of your experiments entryType for me its 4 you need to change this value #}
        <input type="hidden" name="entryType" value="4">
    
        
        <input id="title" type="text" name="experiment[fields][title]">
        <input  type="text" name="experiment[fields][body]">
    
        {# now the cage as a children #}
        <div>
            
            <input type="text" name="cage[0][fields][title]">
            <input type="text" name="cage[0][fields][body]">
            <input type="hidden" name="cage[0][entryId]" value="">
            {# and some Rodents as children for the cages #}
            <div>
                
                <input type="text" name="cage[0][rodents][0][fields][title]">
                <input type="text" name="cage[0][rodents][0][fields][body]">
                <input type="hidden" name="cage[0][rodents][0][entryId]" value="">
            </div>
    
            <div>
                
                <input type="text" name="cage[0][rodents][1][fields][title]">
                <input type="text" name="cage[0][rodents][1][fields][body]">
                <input type="hidden" name="cage[0][rodents][1][entryId]" value="">
            </div>
    
            <div>
                
                <input type="text" name="cage[0][rodents][2][fields][title]">
                <input type="text" name="cage[0][rodents][2][fields][body]">
                <input type="hidden" name="cage[0][rodents][2][entryId]" value="">
            </div>
        </div>
    
        {# and another cage #}
        <div>
            
            <input type="text" name="cage[1][fields][title]">
            <input type="text" name="cage[1][fields][body]">
            <input type="hidden" name="cage[1][entryId]" value="">
            {# and some Rodents as children for the cages #}
            <div>
                
                <input type="text" name="cage[1][rodents][0][fields][title]">
                <input type="text" name="cage[1][rodents][0][fields][body]">
                <input type="hidden" name="cage[1][rodents][0][entryId]" value="">
            </div>
        </div>
    
        <input type="submit" value="Publish">
    
    {# just as an example how you could display errors or at least receive the error object #}
    {% if rodentErrors is defined %}
        {% for errors in rodentErrors %}
            {% for fieldHandle, errorMessages in errors  %}
                {{ fieldHandle }} {{ errorMessages[0] }}
    {% endfor %} {% endfor %} {% endif %}

Please let me know when you need help and feel free to ask what
you like.
If done right, you’ll end up with a structure like this with your
form (note: please ignore the titles…) enter image description here

返信を残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です