{{craftSnippets}}
Home Articles Plugins Starter theme Components on Github Gists About
  • Home
  • Articles
  • Using incognito field plugin for Craft CMS
Posted on Dec 10, 2019 by Piotr Pogorzelski

Using incognito field plugin for Craft CMS

"Favourite category" module code on github gists
Learn how you can use incognito field plugin in your custom Craft CMS modules.
Table of contents:
  • About incognito field
  • Example use case
  • Plugin factory
  • Module code
  • How does it work?
  • Using module

About incognito field #

Incognito field is a plugin that allows you to create fields that are hidden from users or blocked from editing. Such fields can be used to store data generated by custom modules, just as regular fields store user-generated content.

Thanks to the incognito field, your modules can be simpler - no need to create new database tables if you want to attach a bit of data to your elements - like entries, categories or users.

Example use case #

Recently, I was working on Craft website which had a frontend user system. Users could log-in to comment on articles and upvote them. Each article had category - and my client wanted to show users their "favourite category". Such category would be determined by counting visits of articles for each user - "favourite category" for the specific user would be one which articles had most visits from this user.

Plugin factory #

While such functionality required creating a custom module, there was no need for tinkering with database (like adding new tables) in order to store visits data - such data could be kept in the incognito field attached to user field layout. To store and retrieve data, I created a simple module using pluginfactory.io.

Plugin factory creates module (or plugin) scaffolding, saving you tons of work - you can learn more about modules in general in "Enhancing a Craft CMS 3 Website with a Custom Module" article on nystudio blog. Plugin factory allows you to include various functionalities in your modules - for "favourite category", I needed to include variables (functions accessible from Twig).

If it's your first module, you might also want to select "code comments" option - thanks to that, module source code will have comments describing how a variable can be used in the template. Instructions explaining how to install module will be available inside README.md file that comes along with package generated by plugin factory.

Module code #

Module needs two variables:

  • saveArticleVisit - this one saves article ID to incognito field attached to the user when he visits an article.
  • getMostVisited - this one returns "favourite category" for a specific user.

PHP code below defines these variables and should be placed within class declared inside plugin variable file - for module named "example module", file would be src/variables/ExampleModuleVariable.

public $userFieldHandle = 'visitedarticles';

public $categoryFieldHandle = 'articleCategory';

public function saveArticleVisit($article){   

    $user = Craft::$app->getUser()->getIdentity();
    if(!is_null($user)){

    	// get field value
        $visitedJSON = $user->getFieldValue($this->userFieldHandle);
        $visitedIds = (array) json_decode($visitedJSON);

        //if there are not IDs saved yet
        if(is_null($visitedIds)){
            $visitedIds = array($article->id);
            $user->setFieldValue($this->userFieldHandle, json_encode($visitedIds));
            Craft::$app->elements->saveElement($user);
        }

        // if there were IDs saved
        if(is_array($visitedIds) && !in_array($article->id, $visitedIds)){
            $visitedIds[] = $article->id;
            $user->setFieldValue($this->userFieldHandle, json_encode($visitedIds));
            Craft::$app->elements->saveElement($user);
        }

    }
}

public function getMostVisited(){

    $user = Craft::$app->getUser()->getIdentity();
    if(!is_null($user)){

    	// get field value
        $visitedJSON = $user->getFieldValue($this->userFieldHandle);
        $visitedIds = (array) json_decode($visitedJSON);

        if(is_array($visitedIds)){
        	// get entries from IDs savet to field
            $entries = craft\elements\Entry::find()->id($visitedIds)->all();

            //get categories of these entries
            $categoryIds = [];
            foreach ($entries as $key => $entry) {
                if($entry->{$this->categoryFieldHandle}->exists()){
                    $category = $entry->{$this->categoryFieldHandle}->last();
                    $categoryIds[$key] = $category->id;
                }
            }

            // find most often occuring category
            if(!empty($categoryIds)){
                $count = array_count_values ($categoryIds);
                arsort($count);
                $keys = array_keys($count);
                // return category object
                $popularCategory = craft\elements\Category::find()->id($keys[0])->one();
                return $popularCategory;                    
            }

        }
    }
}

How does it work? #

Let's take a look at saveArticleVisit. First, we get current user, check if it does not equals null (which means that nobody is logged in) and retrieve any already existing contents of the incognito field. Field handle is set in userFieldHandle class property to visitedarticles. Contents of the field will consist of a list of entry IDs serialized to JSON - so we need to parse field contents using json_decode function.

If there were no IDs yet, json_decode will return null. In that case, we create an array, put an ID of entry passed to saveArticleVisit into it, encode it into JSON again, set field value and save user object. If some entry IDs were already saved in fields contents, we do pretty much the same - the only difference is that we append IDs to an existing array instead of creating a new one. It's also important to note that we do not save duplicate IDs - each entry ID is recorded only once.

Now for the getMostVisited variable. It also retrieves user field value and decodes it from JSON. Then it uses retrieved array of IDs to queries DB for collection of entries matching these IDs. After that, using foreach loop, IDs of categories of these entries are collected and placed into an array. Finally, using few PHP array-related functions, most often occurring category ID in the array is determined - this is ID of our "favourite category". Using this ID, the category element is queried from DB and returned into the template.

Using module #

Assuming that module is named "example module", this code should be placed in "article" entry template - it will record user visit:

{{ craft.exampleModule.saveArticleVisit(entry) }}

Now, to retrieve "favourite category" - this code can be used:

{{ craft.exampleModule.getMostVisited }}

While testing module, you can set the incognito field to behave like regular text field. Just remember to set it to hidden once you are done - to avoid any accidents when someone enters some random value into it using control panel profile page.


TAGS:
#plugin
If you want to get latest updates on Craft CMS tutorials and components, follow me on Twitter or subscribe to RSS feed.
Quick links for this article:
"Favourite category" module code on github gists
Articles on blog:
  • Frontend testing for Craft CMS websites with Codeception and Cypress
  • Building reactive Craft Commerce product page with Sprig plugin
  • Dynamically generated PDF attachments for Freeform submissions
  • Using template hooks in Craft CMS
  • Alpine JS modal component for Craft CMS
  • Using template UI elements to extend Craft CMS control panel
  • Matrix within a Matrix - possible solutions for Craft CMS
  • Universal email template for Craft CMS
  • Creating attributes table from entry fields in Craft CMS
  • Namespacing forms in Craft CMS
  • Creating map-based navigation for Craft CMS
  • Placeholder image macro for Craft CMS
  • Building AJAX contact form with Craft CMS
  • Using incognito field plugin for Craft CMS
  • Email footer creator made with Craft CMS
  • Infinite scrolling and lazy loading with Craft CMS
  • Using Javascript in Twig templates with Craft CMS
  • Twig templating tips and tricks for Craft CMS
  • Basic SEO functionality for Craft CMS
  • Working with dates in Craft CMS templates
  • Working with SVG images in Craft CMS templates
  • Responsive and lazy-loaded youtube videos with Craft CMS
  • Debugging and inspecting Twig templates in Craft CMS
  • Creating article excerpts with Twig component in Craft CMS
  • Adding favicons to Craft CMS website
  • Truncating text with Twig macros in Craft CMS
  • Universal language switcher for Craft CMS
  • Read time macro for Craft CMS
  • Using attr() function to render HTML attributes in Craft CMS
  • Building dynamic, AJAX based pagination for Craft CMS
  • How to add Disqus comments to Craft CMS website
  • Ellipsis pagination component for Craft CMS
  • Converting email addresses into links using Twig macro
  • Breadcrumb created from URL for Craft CMS
  • Best developer-oriented Craft CMS plugins
  • Search autocomplete component for Craft CMS
  • RSS feed - template component for Craft CMS
  • Testing emails sent by Craft CMS using Mailtrap
  • Quick edit link - Twig component for Craft CMS
  • Filtering entries in control panel using Searchit plugin
  • Fetching routes into Twig templates in Craft CMS


Frontend testing for Craft CMS websites with Codeception and Cypress

Building reactive Craft Commerce product page with Sprig plugin

Dynamically generated PDF attachments for Freeform submissions

Using template hooks in Craft CMS

Alpine JS modal component for Craft CMS

Using template UI elements to extend Craft CMS control panel

Matrix within a Matrix - possible solutions for Craft CMS

Universal email template for Craft CMS

Copyright ©2023 Piotr Pogorzelski