Basic CRUD plugin - example?

13 posts / 0 new
Last post
holmesg
Basic CRUD plugin - example?

Is there an example plugin somewhere to use as a starting point for a fairly simple CRUD (Create, Read, Update, Delete) plugin?

What I'd like to do is to make a simple "featured resources" plugin, that provides an admin page to select a number of resources to feature, and the ability to put a slider of the featured resrouces on the home page. I will also let the slider have a customizable title (e.g. "National Whatever Week", or "Resources for the Disaster That Just Happened").

This would be simple enough to just program, but I'd like to try actually getting it into plugin format. I've looked at the plugin documentation, but I was wondering if there's either a sample plugin, or a specific plugin that you would reccommend that I use as a sort of template or starting point?

 

chalpin
Re: Basic CRUD plugin - example?

No, our documentation does not yet include an example plugin like the one you describe. We'll definitely be thinking about adding such an example in the future.

Three plugins that come to mind that might provide good starting points are  Blog, Pages, and CalendarEvents.  Of those, Pages is probably the simplest.

However, I'm a little bit confused about why you described this as a 'CRUD' example. If I'm understading you correctly, it seems you just want to deal with Resources instead of some custom datatype (as Blog, Pages, and CalendarEvents do).  If this is correct, then the Create, Update, and Delete functionality are already in the base software, such that all you'd really need in the plugin is 'Read'.

If I were trying to implement the functionality you've described (as I understood it anyway), I would add an optional Controlled Name metadata field to your Resources, with a name like 'Featured Resource Type'. The values for this field would be "National Whatever Week" or "Resources for the Disaster That Just Happened", etc.

In the plugin, I would generate a slider based on the possible values for that field, and select a resource to display based on the currently selected slider value.

holmesg
Featured Resources plugin

Thanks for your help; I'm starting to implement this now as you suggested.

Questions that I have so far:

1. During plugin installation, how do I programmatically add the Controlled Name field ('Featured Resource Type') for use with resources? I'd like the plugin to set this up automatically at installation. To create the Controlled Name field and add a few sample values/choices for the field.

2. How do I create a configuration setting ($this->CfgSetup[etc.) to allow the user to choose a Featured Resource Type to select resources to display (and also to use as a title)? In other words a setting whose possible values are the Featured Resource Types (e.g. "National Whatever Week" or "Resources for the Disaster That Just Happened").

3. Is there a "correct" way to select resources by value of the Controlled Name field, or should I just figure it out from the database?

chalpin
Re: Featured Resources plugin
  1. The best method to use for programmatic field creation is MetadataSchema::AddFieldFromXml().  The Install() method in the CalendarEvents plugin has an example of this.
     
  2. To populate a configuration setting with values from a controlled name, you'd create an "Option" configuration, the populate the possible values using GetPossibleValues() on the result of a Schema->GetFieldByName() for your desired field. It would work somewhat like the setup for "NotificationTemplate" inside the Blog plugin.
     
  3. The safest thing is to use the SearchEngine.  That way, your code won't depend on the specifics of the database layout.  I'd start with something like this, seasoning as required:
    $SearchGroups = array();
    $SearchGroups["MySearch"]["SearchStrings"]["My Controlled Name"] =
        array("=National Whatever Week", "=Disaster That Just Happened");
    $SearchGroups["MySearch"]["Logic"] = SearchEngine::LOGIC_OR;
    $SearchGroups["Released"]["Release Flag"] = array("=1");
    $Engine = new SPTSearchEngine();
    $Results = $Engine->GroupedSearch($SearchGroups, 0, PHP_INT_MAX);

 

 

holmesg
Re: Featured Resources plugin

Thank you for those pointers!

The client has changed the course a bit now, though. The idea now is to have one or more special classifications, and then select a classification to feature.

 

So now I need to figure out how to:

1. Populate a configuration option with Classifications - a somewhat similar strategy as using controlled name values?

2. Search programmatically (I presume this is still the best strategy) by the selected classification.

chalpin
Re: Basic CRUD plugin - example?

1. Yes, you should be able to use the same kind of strategy for a Classifcation as a ControlledName.

2. If you're looking for an exact match with a classification, then the code I provided above should still work (e.g., if you wanted "Disasters -- That Thing").  If you want to be able to search for a parent classification (e.g., "Disasters") and have the results contain resources which having child classification (e.g., "Disasters -- That thing"), that's slightly thornier. I'm currently working on an enhancement to the CWIS SearchEngine that will add a "begins with" predicate to support exactly this use case.  In the mean time, the safest way to handle this would be to explicitly assign the parent classification (e.g. "Disasters") to each resource that should appear in the rotation, in addition to any child classes.  So, you might have a resources with "Disasters" and "Disasters -- That thing" both assigned.

holmesg
Re: Basic CRUD plugin - example?

I think I'm going wrong trying to get a reference to the Classification field, in order to populate the dropdown for plugin configuration:

 

        $SchemaId = GetArrayValue($_GET, "SC", MetadataSchema::SCHEMAID_DEFAULT);
        $Schema = new MetadataSchema($SchemaId);
        $theField = $Schema->GetFieldByName("Classification");
        $FeaturedClassificationSource = $theField.GetPossibleValues();

        $this->CfgSetup["FeaturedClassification"] = array(

         "Type" => "Option",

         "Label" => "Classification to Feature",

         "Help" => "The Classification to use for Featured Resources.",

          "Default" => -1,

           "Options" => $FeaturedClassificationSource);

 

 

The call to GetPossibleValues() fails.

chalpin
Re: Basic CRUD plugin - example?

$FeaturedClassificationSource = $theField.GetPossibleValues();

Should instead be

$FeaturedClassificationSource = $theField->GetPossibleValues();

In PHP, the period is not a member access operator, just string catenation. So instead of calling the "GetPossibleValues" method from the metadata field, your code was coercing the field to a string and attempting to combine it with the result of a nonexistent GetPossibleValues() in the global scope.

holmesg
Re: Basic CRUD plugin - example?

Gack ... color me red. Eek.

(In my defense, I am somewhat ill today ...)

Thanks!

chalpin
Re: Basic CRUD plugin - example?

I'm honestly somewhat surprised that PHP doesn't provide a useful error message in this situation, especially with so many of the C-like languages using dot to get at object/struct members.  Instead it just does something kind of weird and unexpected.  Definitely a "principle of least astonishment" violation, in my opinion.

holmesg
Re: Basic CRUD plugin - example?
OK, I've got further ... I've got the configuration setting to designate the classification for featured resourecs working.
 
I'm not finding any Resources, though (though there are some assigned to that category) ... I don't think I'm getting the search right.
 
            #retrieve list of featured resources
 
            $theClassification = new Classification($this->ConfigSetting("FeaturedClassification"));
 
            $theClassificationName = $theClassification->FullName();
            
            
            $SearchGroups = array();   
            //$SearchGroups["MySearch"]["SearchStrings"]["My Controlled Name"] = array("=Apple Dumpling Day", "=Disaster That Just Happened");
            $SearchGroups["MySearch"]["SearchStrings"]["My Controlled Name"] = array('=' . $theClassificationName);
            
            $SearchGroups["MySearch"]["Logic"] = SearchEngine::LOGIC_OR;
            $SearchGroups["Released"]["Release Flag"] = array("=1");
            $Engine = new SPTSearchEngine();
 
            $Resources = $Engine->GroupedSearch($SearchGroups, 0, PHP_INT_MAX);
holmesg
Re: Basic CRUD plugin - example?

OK, I've got further ... I've got the configuration setting to designate the classification for featured resourecs working.

I'm not finding any Resources, though (though there are some assigned to that category) ... I don't think I'm getting the search right.

            #retrieve list of featured resources

            $theClassification = new Classification($this->ConfigSetting("FeaturedClassification"));
 
            $theClassificationName = $theClassification->FullName();
            
            
            $SearchGroups = array();   
            //$SearchGroups["MySearch"]["SearchStrings"]["My Controlled Name"] = array("=Apple Dumpling Day", "=Disaster That Just Happened");
            $SearchGroups["MySearch"]["SearchStrings"]["My Controlled Name"] = array('=' . $theClassificationName);
            
            $SearchGroups["MySearch"]["Logic"] = SearchEngine::LOGIC_OR;
            $SearchGroups["Released"]["Release Flag"] = array("=1");
            $Engine = new SPTSearchEngine();
 
            $Resources = $Engine->GroupedSearch($SearchGroups, 0, PHP_INT_MAX);
 
chalpin
Re: Basic CRUD plugin - example?

These search groups look fine to me.  If you construct an equivalent AdvancedSearch, does it find anything?  You might stick a print("<pre>"); print_r($G_SearchGroups); print("</pre>"); at the end of pages/AdvancedSearch.php in a development site to see examples of how the search groups look for various searches.