web-dev-qa-db-fra.com

Comment Joomla 3 utilise-t-il des tags en extension?

Comment réaliser que les tags fonctionnent sur mon extension personnalisée? J'ai essayer de suivre https://docs.joomla.org/J3.2:Using_Tags_in_an_Extension ce guide pas à pas, mais je ne parviens toujours pas à enregistrer les balises dans la base de données. Alertes système "L'enregistrement a échoué avec l'erreur suivante: (vide)". Je ne sais pas quelle est l'erreur ....

Quelqu'un at-il une telle expérience sur le développement des tags qui peut m'aider? Je vous remercie !!!!

6
Jacky Kwan

Vous pouvez utiliser la fonctionnalité de balises dans votre extension personnalisée comme suit:

  1. modèles/forms/formfile.xml -

    <field name="tagfieldname" type="tag" mode="ajax" label="Tag Field Name" description="" multiple="true" custom="allow" required="true" />

  2. tables/filename.php - ajoute le code suivant dans la méthode bind():

    public function bind($array, $ignore = '')
    {    
      if (!empty($array['tagfieldname']) ) {
      // Load the tags helper.
      require_once JPATH_ADMINISTRATOR . '/components/com_tags/helpers/tags.php';
    
    // Get the allowed actions for the user
    $canDo = TagsHelper::getActions('com_tags'); // The helper get the user and the component name itself
    
    // Load the tags model.
    require_once JPATH_ADMINISTRATOR . '/components/com_tags/models/tag.php';
    JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_tags/tables');
    
    // Get an instance of the table for insertion the new tags
    $tagsModel = TagsModelTag::getInstance('Tag','TagsModel');
    
    $tags = array(); // Initialization of the tag container must be processed
    
    // If tags is an array, store-mode
    if ( is_array($array['tagfieldname']) ) {
        // "Allow user creation" mode must be activated (default) in the component creation field
        // Save the tags does not exist into the table tags and get its id for save the entire Item with the proper data
        foreach ($array['tagfieldname'] as $singleTag) {
            // If there is any new tag... create it to get the id and save into the table #__COMPONENT_NAME_TABLE_NAME
            if ( strpos($singleTag, "#new#") !== FALSE ) {
                $user           = JFactory::getUser();
                $userId         = $user->id; // For writing permissions 
                $tagName        = str_replace("#new#", "", $singleTag);
                $tagAlias       = $tagPath = preg_replace('/\W+/', '-', $tagName); // Tags alias filter
                $tagMetadata    = array(
                        "author"=>""
                        , "robots"=>""
                        , "tags"=>null
                );
    
                // The data tag field row
                $data = array(
                        "parent_id" => 0
                        , "path" => $tagPath
                        , "title" => $tagName
                        , "alias" => $tagAlias
                        , "created_by_alias" => $user
                        , "created_user_id" => $userId
                        , "published" => 1
                        , "checked_out" => 0
                        , "metadata" => json_encode($tagMetadata)
                );
    
                // Finally, store the tag if the user is granted for that
                if ( $canDo->get('core.create') ) {
                    $table = $tagsModel->getTable();
                    $table->bind($data) ? $table->store($data) : exit;
                    $tags[] = $table->id; // And store the insert_id
                }
            }
    
        // NOT new Tag (already exists)
        // $singleTag is the tag id
        else
            $tags[] = intval($singleTag);
        }
    
        // Override the tags array, because we should need to change the id before field saving
        // The field in database will look like "299,345,567,567"
        $array['tagfieldname'] = implode(',', $tags);
    }
    }
    else {
        $array['tagfieldname'] = '';
    }
    return parent::bind($array, $ignore);
    }// bind() ends
    
3
Liz.

Pour Joomla 3.7.x et chaque composant personnalisé, j'ai pris la réponse de @liz et ai placé le code dans une fonction distincte que vous pouvez appeler de partout et l'utiliser où vous le souhaitez.

De plus, j'ai déplacé l'User-factory au-dessus de la foreach, car il suffit de l'appeler une fois, pas pour chaque boucle. Et j'ai enlevé le $canDo, car cela ne fonctionne pas, car TagsHelper n'est pas disponible comme ceci. Peut-être que cela peut être fait avec n'importe quel autre contrôle d'accès-contrôle?

function saveJoomlaTags($tags, $created_by_alias="", $note="") {

        // Load the tags model.
            require_once JPATH_ADMINISTRATOR . '/components/com_tags/models/tag.php';
            JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_tags/tables');

        // Get an instance of the table for insertion the new tags
            $tagsModel = TagsModelTag::getInstance('Tag','TagsModel');

        // If tags is not an array, return nothing.
            if ( !is_array($tags) ) {
                return "";
            } 

        $user = JFactory::getUser();
        $return = array();

        // "Allow user creation" mode must be activated (default) in the component creation field
        // Save the tags does not exist into the table tags and get its id for save the entire Item with the proper data
            foreach ($tags as $singleTag) {
                // every custom-entered tag starts with "#new#", every exsting tag is the ID.
                    if ( !strBeginsWith($singleTag, "#new#")) { // see pm_helper.
                        $return[] = intval($singleTag);
                        continue;
                    }

                // A new Tag must be saved to the DB first.
                    $tagName        = str_replace("#new#", "", $singleTag);
                    $tagAlias       = $tagPath = preg_replace('/\W+/', '-', $tagName); // Tags alias filter
                    $tagMetadata    = array();
                    $tagMetadata["author"]  = "";
                    $tagMetadata["robots"]  = "";
                    $tagMetadata["tags"]    = "";


                // The data tag field row
                    $data = array(
                            "parent_id" => 0
                            , "path" => $tagPath
                            , "title" => $tagName
                            , "alias" => $tagAlias
                            , "created_by_alias" => $created_by_alias
                            , "created_user_id" => $user->id
                            , "published" => 1
                            , "language" => "*"
                            , "checked_out"=> 0
                            , "metadata" => json_encode($tagMetadata)
                            , "note" => $note
                    );

                // Finally, store the tag if the user is granted for that
                    $table = $tagsModel->getTable();
                    $table->bind($data) ? $table->store($data) : print "Fehler beim Speichern der Tags. Siehe ".__FILE__.__LINE__;
                    $return[] = $table->id; // And store the insert_id                       

            } // foreach 

        // Override the tags array, because we should need to change the id before field saving
        // The field in database will look like "299,345,567,567"
            $return = implode(',',$return);

        return $return; // a list of IDs.

    } // saveItemTags()

Vous aurez également besoin de cette fonction d'assistance "strBeginsWith":

    function strBeginsWith($str, $beginsWith) {
       if (strpos($str, $beginsWith) === 0) {
           return true;
       }
       return false;
   }
1
Robert

Très probablement, quelque chose ne va pas avec votre #__content_types entrées.

Tout d’abord, vous devez enregistrer vos content_types pour vos vues, comme décrit ici:

Ensuite, vous devez faire attention aux valeurs des champs de vos content_types.

Plus spécifiquement pour sauvegarder les tags dans le #__contentitem_tag_map table pour votre extension, les champs obligatoires pour votre content_type sont:

type_id, type_title, type_alias, table, field_mappings

Assurez-vous que type_alias et le field_mappings contient des données valides. Par exemple, une simple erreur de syntaxe dans field_mappings entraînerait des erreurs, comme celle que vous avez eue.

0
FFrewin