Jump to content

Community

  • We are moving our Documentation to our new Guides area.

    As articles are moved they will be deleted. Please start following the new guides. We look forward to publishing all our new guides soon!

  • Sign in to follow this  

    Introduction to Nodes (*)


    Charles

     

    Nodes are created by an administrator. While throughout the IPS Community Suite, nodes have various purposes, this document explores their use as containers for content items.

    In the IP.Board application, a forum is a node - forums contain topics, which are content items. In the IP.Downloads application, a category is a node - categories contain files, which are content items.

    Note: Nodes do have the ability to have sub-nodes of a different class to themselves. Because this is complicated and not usually needed for content items, methods and properties pertaining to it have been omitted in this documentation.

    11

    Requirements

    The Model
    Skeleton
    namespace IPS\yourApp;

    class _YourClass extends \IPS\Node\Model
    {
    

    /**
    * @brief [ActiveRecord] Multiton Store */

         protected static $multitons;
    

    /**
    * @brief [ActiveRecord] Default Values */

         protected static $defaultValues = NULL;
    

    /**
    * @brief [ActiveRecord] Database Table */

         public static $databaseTable = 'table';
    

    /**
    * @brief [ActiveRecord] Database Prefix */

         public static $databasePrefix = 'prefix_';
    

    /**
    * @brief [Node] Node Title */

         public static $nodeTitle = 'categories';
    

    /**
    * Get URL
    *
    * @return \IPS\Http\Url */

         public function url()
         {
    
              return \IPS\Http\Url::internal( ... );
         }
    
    /**
     * [Node] Add/Edit Form
     *
    
    • *  @param \IPS\Helpers\Form

    • *  @return void */

    $form The form

    12

         public function form( $form )
         {
    
              $form->add( ... );
         }
    

    }

    Inheritance

    Your model extends a number of classes. In turn, these are:-

    \IPS\Node\Model
    

    Provides the features of Nodes. It contains all the code for the various optional features of content items which you will activate by adding properties and interfaces to your model.

    \IPS\Patterns\ActiveRecord
    

    Provides the functionality to load items from the database, work with their properties, save and delete them.

    Required Methods and Properties

    array static $multitons
    array static $defaultValues;

    Simply requirements of \IPS\Patterns\ActiveRecord - you do not need to do anything other than define them.

    string static $databaseTable
    Is the name of the database table which you store your Nodes in (you’ll need to create this).

    string static $databasePrefix
    If all of the columns in your database table start with the same prefix, you can define that here and then you do not need to specify it every time you look up the value of a column. It is important that your database table has a column which called {$databasePrefix}id containing a numeric primary key.

    string static $nodeTitle
    Should be a language key containing a word which explains what your nodes are (for example, “Forums” or “Categories”).

    string static $databaseColumnOrder
    Should be the column in your database table (without prefix) which contains the position number that nodes will be pulled in order of (the central code will handle setting and using the value, but you have to create a field for it - it should be an INT column).

    url()

    Should return an \IPS\Http\Url object pointing to the location on the front-end where users can view the content items in your node (how to generate this page is covered in Chapter 2).

    13

    form( \IPS\Helpers\Form $form )
    

    See the form section below.

    Optional Methods

    bool static $nodeSortable
    If you set this to FALSE (it is TRUE by default), administrators will not be able to reorder the nodes.

    bool static $modalForms
    

    If you set this to TRUE (it is FALSE by default), the add/edit forms will open in modal windows.

    Available Methods

    In addition to those provided by \IPS\Patterns\ActiveRecord, a number of additional methods are available:

    static roots()
    

    Returns an array of nodes. If you implement Parent/Children relationships (see below) it will return only those with no parent.

    static search( string $column, string $query, string $order=NULL, array $where )
    Returns an array of nodes that match the search.

    getButtons( \IPS\Http\Url $url )
    

    Returns an array of buttons to show in the node tree.

    Getters and setters

    As already explained in the introduction, the \IPS\Patterns\ActiveRecord class allows you to provide methods to create getters and setters. Certain special properties will be attempted to be get and set by core methods so you must create methods to handle them. In most cases you will not need to implement a method as the method that already exists in \IPS\Node\Model will be sufficient - only create a method if not (for example, you will always want to create a get__title() method but almost never need a get__id() method).

    Property

    Description

    Get/Set

    Default value returned by \IPS\Node\Model if you do not create a method

    $_id

    Should return the ID number of your node.

    Get only

    The value of the “id” column in the database.

    $_title

    Should return the title of your node.

    Get and search

    blank string

    $_description

    Should return the description of your node, or NULL if not applicable.

    Get only

    NULL

    14

    Property

    Description

    Get/Set

    Default value returned by \IPS\Node\Model if you do not create a method

    $_badge

    Can be used to return a badge to show when viewing nodes in ACP. See phpDocs.

    Get only

    NULL

    $_icon

    Can be used to display an icon in the row when viewing nodes in the ACP. Return a CSS class name for the icon.

    Get only

    NULL

    $_enabled

    If implemented, will add an “Enabled” / “Disabled” badge that can be clicked on to toggle status. You should implement this if your nodes have a concept of being enabled/disabled.

    Get and Set

    NULL

    $_locked

    If you are using $_enabled, this can be used to specify that an individual node cannot be enabled/ disabled and is locked in it’s current status.

    Get only

    NULL

    $_position

    Returns the position of the node.

    Get only

    The value of the column in the database represented by $databaseColumnOrder

    $_items

    The number of content items in the node (see chapter 2)

    Get and Set

    NULL

    $_comments

    The number of comments on content items in the node (see chapter 3)

    Get and Set

    NULL

    $_reviews

    The number of reviews on content items in the node (see chapter 3)

    Get and Set

    NULL

    For an example of how this might work - the titles of nodes are almost always stored as language strings in the database, so most nodes have a method that looks like this:

    protected function get__title() {
         return \IPS\Member::loggedIn()->language()-
    
    >get(“yourApp_category_{$this->id}”);
    }
    

    Note that “_title” is sometimes sent to the search method (see Available Methods below). You may therefore need to override this method to get the nodes that match the searched for title. As a shortcut, if you are using language strings for titles in the manner described above, you can simply add the static $titleSearchPrefix property to your model with the prefix.

    public static $titleSearchPrefix = 'yourApp_category_';
    

    Forms

    15

    When viewing your nodes in the Admin CP, an add/edit form will automatically be made available. You need to define a form( \IPS\Helpers\Form $form ) method to define the form elements to show. For example:

    /**
     * [Node] Add/Edit Form
     *
    
    • *  @param \IPS\Helpers\Form

    • *  @return void */

    $form The form

         public function form( \IPS\Helpers\Form $form )
         {
    
              $form->add( new \IPS\Helpers\Form
    \Translatable( 'category_title', NULL, TRUE, array( 'app' =>
    'yourApp', 'key' => ( $this->id ? "yourApp_category_{$this->id}" :
    NULL ) ) ) );
    
              $form->add( new \IPS\Helpers\Form
    \YesNo( 'category_example', $this->example ) );
    

    }

    This will build a form with 2 elements - a Translatable field allowing the admin to set a title, and a YesNo field for another property.

    When the form is saved, any fields which match columns in the database table will be set automatically. However, you may need to do additional work - in this example, because the title is translatable, it cannot be stored in a specific database column - so we need to store it in the language system. This can be done by overriding the saveForm( array $values ) method. For example:

         /**
          * [Node] Save Add/Edit Form
          *
    
    • *  @param array $values Values from the form

    • *  @return void */

           public function saveForm( $values )
           {
      
                // Need to do this as if we’re creating a new node, we
      won’t have an ID yet and the language system will need one to
      store the title.
      
                if ( !$this->id )
                {
      
                     $this->save();
                }
      
                \IPS\Lang::saveCustom( 'yourApp',
      "yourApp_category_{$this->id}", $values['category_title'] );
      
                parent::saveForm( $values );
           }
      

    16

    The Controller
    Skeleton
    namespace IPS\yourApp\modules\admin\yourModule;

    class _yourController extends \IPS\Node\Controller
    {
    
         /**
          * Node Class
          */
    
         protected $nodeClass = 'IPS\yourApp\YourClass';
    }
    

    Introduction

    The controller, just by being defined, will create a page where administrators can view and manage nodes. As you add more features to your Content Item, the controller will perform more actions.

    17

    Parent/Child Relationship Introduction

    Nodes can be children of other nodes, which is almost always the case for nodes that contain content items (for example, a forum can be a sub forum of another subforum), specify the column in your database table (without prefix) which contains the parent’s ID number.

    Other Requirements

    None.

    Behaviour that changes once implemented

    The controller will automatically handle displaying parent/child relationships and allow nodes to be dragged into one another.

    Additional methods available once implemented static roots()

    Returns an array of nodes which do not have a parent.

    parent()

    Returns the immediate parent node.

    parents()

    Returns an Splstack of all parent nodes (the immediate parent node, then that’s parent node, etc,.)

    hasChildren()

    Returns a boolean value indicating if the node has children.

    childrenCount()

    Returns the number of children.

    children()

    Returns an array of child nodes.

    How to implement

    Add a static property to your model, $databaseColumnParent, containing the name of the database column (without prefix) which contains the ID number of the parent node.

    If your application was originally designed for a previous version of IPS Community Suite and uses a value other than 0 to indicate the node has no parent, add an additional static property, $databaseColumParentRootValue, specifying what that value is.

    18

    ACP Restrictions Introduction

    ACP Restrictions allow administrators to restrict other administrators to certain parts of the control panel.

    Other Requirements

    None.

    Behaviour that changes once implemented

    The controller will automatically check ACP restrictions and deny access to disallowed areas.

    Additional methods available once implemented

    static restrictionCheck( string $key ) static canAddRoot()
    canAdd()
    canEdit()

    canCopy()
    canManagePermissions()
    canDelete()

    All methods returns a boolean value indicating if the member currently logged in can perform the action.

    How to implement

    First, create ACP Restrictions in the developer center for your application as desired.

    Then, add a static property to your model, $restrictions, containing an array with 3 elements:
    app should contain the application key which holds the restrictions
    module should contain the module key which holds the restrictions

    The third proper depends on how specific you want the restrictions to be - see below

    There are 3 ways to implement:

    1. Ifyouwanttomanuallyspecifywhichactionsshouldcheckwhichpermissions,adda third element called map which should be an associative array. The keys should be add, edit, permissions (only necessary if your node supports permissions) and delete. The values should be the restriction keys to check for those actions.

    19

    2. Ifyouwanttousethosekeyswithaprefix(forexample,yourrestrictionkeysare “foo_add”, “foo_edit”, etc.), add a third element called prefix specifying the prefix (in this example, “foo_”.

    3. Ifyouwanttojustuseasinglerestrictionforallpermissions,addathirdelementcalled all with the value as that restriction key.

    20

    Front-End Permissions Introduction

    Permissions allow administrators to control which member groups can perform which actions (like see content items, create new content items, comment on content items, etc.) in each node.

    Other Requirements

    None.

    Behaviour that changes once implemented

    The hasChildren(), childrenCount() and children() methods will only return the child nodes that the currently logged in user has permission to view. All methods take two parameters to control this behaviour:

    children( string $permissionCheck=‘view', \IPS\Member $member = NULL )

    $permissionCheck controls which permission is checked. $member controls which member to check for (if NULL, the currently logged in member is used).

    loadAndCheckPerms(...) will now throw an OutOfRange exception if a node the currently logged in user does not have permission to view is loaded.

    Additional methods available once implemented

    static canOnAny( string $permission, \IPS\Member $member = NULL )
    Returns a boolean value indicating if the $member (currently logged in member if NULL) has permission to perform the $permission action on any node. This can be used, for example, to determine if a “Create New Content Item” button should show.

    can( string $permission, \IPS\Member $member = NULL )
    Behaves the same as canOnAny() but is an instance method, for checking permission on a particular node.

    permissions()

    Returns an array with the node’s row from the core_permission_index database table, which contains which groups have which permissions.

    How to implement

    First, you need to make your model implement the \IPS\Node\Permissions interface. 21

    Then, add three new properties to your model: $permApp

    The application key your class belongs to.

    $permType
    A unique key to represent your class in the core_permissions_index table (for example, “forums” or “categories”).

    $permissionMap
    You are allowed up to 7 different permissions - this property should be an array mapping the keys you want to use (which are used when calling methods like can()) to the columns that will be used to store that permission in the core_permisisons_index table. Each value must either be the string “view” (which is required) or a number between 2 and 7.
    For example:

    public static $permissionMap = array( 'view' => 'view', 'read' => 2, 'add' => 3, 'download' => 4, 'reply' => 5, 'review' =>6

    );

    In this example, the permission keys available are “view”, “read”, “add”, “download”, “reply” and “review”. “view” (can see the node), “read” (can see content items in the node) and “add” (can create new content items) are always required. “reply” is required if your content items can be commented on. “review” is required if your content items can be reviewed.

    In the Admin CP, the permission matrix will show the permissions in the order you define them here. The columns in the matrix will look for language string with the key “perm__{$key}” - so, in this example, a new language string with the key “perm__download” would need to be created (“perm__view”, “perm__read”, etc. are already defined in the core).

    
 

    Example: 

    Sign in to follow this  


    User Feedback

    Recommended Comments

     You are allowed up to 7 different permissions - this property should be an array mapping the keys you want to use (which are used when calling methods like can()) to the columns that will be used to store that permission in the core_permisisons_index table. Each value must either be the string “view” (which is required) or a number between 2 and 7.

     So the values 2 through 7 are alternatives to the strings ('read', 'add', 'download', 'reply', 'review')? This is confusing to me. What exactly are we mapping here.

    Share this comment


    Link to comment
    Share on other sites

     So the values 2 through 7 are alternatives to the strings ('read', 'add', 'download', 'reply', 'review')? This is confusing to me. What exactly are we mapping here.

    ​well they can hold whatever keys you want to give them, when you do a perm check, you don't check it against 2/3/4/5/6/7, you would check against its, so if you had:

        public static $permissionMap = array(
            'view' 				=> 'view',
            'deny'				=> 2,
            'redirect'				=> 3,
            'review'			=> 4,
            'reply'				=> 5,
        );

    you would call "redirect" in the perm check, not 3.

    Share this comment


    Link to comment
    Share on other sites

    Thanks for the clarification. So in other words, the value assigned to any key in the permission map must be one of ( 'view', 2, 3, 4, 5, 6, or 7). The key may be whatever you want to call it, as long as it has one of those values.

    Share this comment


    Link to comment
    Share on other sites

     So the values 2 through 7 are alternatives to the strings ('read', 'add', 'download', 'reply', 'review')? This is confusing to me. What exactly are we mapping here.

    ​go into database table "core_permissions_index" and try to find column "perm_3" this is used for redirect permission.

    map is used to interact with a words insted of the numbers.

    Edited by BomAle

    Share this comment


    Link to comment
    Share on other sites

×
×
  • Create New...