Each Content Item (such as a note, image, document or table) has a number of Control Icons attached to it. The most common ones are:
Common controls are made available to the individual plugins using methods provided by the pluginSupport
class.
Individual plugins are free to make use of those controls as they deem fit - though a uniform look is encouraged.
Some plugins also implement special controls; for example, the notes
plugin (formatted HTML notes) also implements a revision (history) feature - and provides a control to access that feature.
EXAMPLE: outline of implementing a control in a plugin
The documents
plugin (to store documents of any type, such as PDF or MS Word files), like all plugins, needs to provide a DELETE control. All it has to do is:
pluginSupport
class, which returns the control (HTML code, including graphs and links.) The code for the request is:$this->pluginSupport->controlLinks_Delete($this->pluginCode, $docID, $categoryID);
deleteObject($objectID)
, to carry out the actual deletion of the Content Item. This method gets invoked by the control generated in step 1.
NOTES
Every plugin is required to provide a set of standard methods to implement (its share of) the work to perform the actual actions of the various standard controls. The Core module automatically takes care of the rest of the work.
For example, the deleteObject($objectID)
implemented by the documents
plugin takes care of deleting the actual document file, as well as deleting the record of that document kept by the plugin. The higher-level method controlLinks_Delete
, provided by the pluginSupport
class, in addition to invoking the plugin-specific deleteObject
method, also invokes methods provided by the Core module. These methods take care of, for example, clearing records associated with general properties of the Content Item being deleted, such as its size and permissions.
In short: a lot of the work is done by the Core module, and accessed by individual plugins through the pluginSupport
class. This makes plugin implementation vastly easier.
createDialogBox
in viewer.php, with the last argument being the JS function populateEditMetadataBox
populateEditMetadataBox
, in viewer.php, fetches from the server the HTML code to provide a way to edit the specified Content Item's metadatafetchFromServer
, in core.js, which uses the fetch
API to contact userRequestsHandler.php
plugin=cm&handler=editMetadata&mode=embed&itemType=d&itemID=1234
, where 1234 is the ID of the document in question. The full server invocation is: userRequestsHandler.php?plugin=cm&handler=editMetadata&mode=embed&itemType=d&itemID=1234
contentManager
(for now inside siteInitialization.php). That's the class that provides the requested method handler_
editMetadata
(the "handler" prefix is implied.)What happens when a user requests to add a new content item? For example, when creating a note or a site link (annotated web bookmark)... or uploading a photo or document.
BRIEF SUMMARY FOR PLUGIN DEVELOPERS
Provide the following methods in your plugin class: handler_addContentModule()
and addObject()
:
handler_addContentModule()
: assembles and returns HTML (typically a form) to let the user define the new content.addObject()
: takes care of the housekeeping operations involved in adding the new content item. It must return the ID assigned the newly-added content item; in case of failure, the plugin is expected to throw an exception.Plugins may either handle their own database tables (high-level API provided) or, as of version 3.1, take advantage of a new (RDF-style) triple store, which is strongly recommended.
EXAMPLES:
If your plugin uses a form to create new content, you can copy and adapt, for example, the counterpart methods in the siteLinks
plugin (in the file plugins/siteLinks/siteLinks.php
)
If your plugin uploads files (such as photos or documents), see also Uploading Content.
PART 1 - Letting the user specify what they want to add : CLIENT-SIDE, viewer.php
addItemList
(defined in viewer.php
).<a href="javascript:addItemList(type, ID)"> </a>
, where type (for example, "n") and ID (for example 12) refer to the previous Content Item, i.e. the item (such as a note or image) immediately before the icon. In case of insertions before the first item of the page (i.e. at the very top of the page), by convention type = ""addItemList
JavaScript function (defined in viewer.php
) toggles the visibility of the box used to add Content Items (initially hidden), if it already exists - or dynamically creates it otherwiseaddItem_XYZ
for some value XYZ, where XYZ is of the form "previousItemType_previousItemID" (e.g. "n_12"), or "0" if inserting at the very beginning of the page. That ID value is used to uniquely identify the box to use, and it indirectly indicates the position (in the ordered list of Content Items attached to the current Category) after which to insert the new itemcontentAdditionBox
(defined in viewer.php
); in other case, it's generated dynamically by JavaScript.<a href='javascript:addItem($addBlockID, \"n\")'>Create Note</a>
("n" is the code for the "notes" plugin)addItem
, with the following arguments:addImmediateItem()
, for Content Items that require no parameters at their creation (e.g. the clock plugin).addImmediateItem()
takes the following arguments:
PART 2 - Specifying parameters to the newly-created Content Items (when applicable)
addItem
creates and displays a dynamically-generated, plugin-provided DIV element (such as a form) that can be used to add a Content Item of the specified type at the requested position (order ID) on the page.addItem
replaces the original, generic "Add new content" box (for all plugin types) with one specific to the chosen plugin, with an actual data-entry formobtainAddFormFromServer
, which contacts ther server-side script pluginHandler.php
using an XMLHttpRequest()
call
PART 3 - Letting the user specify what they want to add : SERVER-SIDE, pluginHandler.php
pluginHandler.php
, which dispatches the call to the appropriate plugin object (depending on the plugin code), and invokes a method called handler_addContentModule()
in that plugin objecthandler_addContentModule()
handler_addContentModule()
method must assemble and return an HTML form. This form gets returned to the front-end XMLHttpRequest()
call, and back to the JavaScript function addItem
, which inserts it in the page, in lieu of the original new-content addition boxformBuilder
class (one of Brain Annex common modules)doAddContent.php?type=CODE
, where CODE is the plugin code. The form must also pass hidden inputs for categoryID
, order
and redirect
PART 4 - Adding the new content specified by the user
doAddContent.php
is part of the core module. The bulk of the work is done in the invocation of the method contentManager->addNewContentItem
addNewContentItem
method (part of the contentManager
class, for now hosted in the file siteInitialization.php
) dispatches tasks to various housekeeping modules, such as permissions
, resourceUsage
and categories
... and finally invokes the plugin-specific method addObject()
, for the plugin that started the new content addition process. This concludes the operations by the form handler. The new Content Item is now created and appropriately catalogued - with most of the work done by the core modules, and just the bare minimun by the plugin itself!viewer.php
) offer pop-up boxes to add new contentdoAddContent.php
scriptdoAddContent.php
) contacts:uploader
module to take care of the actual uploadcore
module, to handle permissions, resource usage, setting the position of the uploaded item on the page, and to command the individual content-specific plugin to do its own management (such as maintaining a table of items and their metadata, creating thumbnails of uploaded images, etc.)
viewer.php
) instantiates the core module (aka the orchestrator module), which in turn initiates all plugins and other modulesaddItemList
, with the position in the page passed as argumentaddItemList
toggles the reveal/hide a box used to add Content Items. The box's ID is addItem_n
for some n, where n is the position on the page. The reveal/hiding toggling is handled by the JavaScript function toggleBlockElement
addBlock
; it primarily contains HTML links (one per type of content item) that invoke JavaScript functions or PHP scriptsaddItem
, with 2 arguments: the ID of the pop-up box (representing the position in the page where to insert the new item) and the code for the plugin that handles that particular content type. For example, for document upload, the involved plugin is "documents", with plugin code "d"addItem
uses XMLHttpRequest to contact the pluginHandler.php
script on the server. Various arguments are passed, including the code for the plugin type (for example "d" for "documents") and the method to use, which for uploading is addContentModule
pluginHandler.php
script on the server receives the XMLHttpRequest, then selects the appropriate plugin (for example "documents") and invokes the passed method (addContentModule
). Each content plugin that provides file upload must implement method by that name: it generates and returns an HTM form to upload files specific to that plugin typepluginHandler.php
), and passed through XMLHttpRequest to the invoking JavaScript, which inserts the HTML form on the page<form>
tag with class='dropzone' id='myDropzone_pluginCode'
, where pluginCode varies by plugin. The dropzone elements are used to interface with the dropzone software, which handles the front-end of the uploads, including the drag-and-drop graphicsdoAddContent.php
script. It contacts the uploader
module, which receives and processes the file just uploaded to the server. The uploader also accepts a customizable function, named nameHandler
, provided by the calling code in the doAddContent.php
scriptnameHandler
, is where plugin-specific actions take place. The nameMapping
method of the plugin in question (for example, "documents") is invoked – the plugins decides what name to store the file under. Next, the addNewContentItem
method of the core module is invoked, with information about the just-uploaded file (such as its type, size and the original file name.)addNewContentItem
method of the core module (in the file siteInitialization.php
) performs various actions:isAddAllowed
)permissions
module and categories
module to set the permissions of the newly-uploaded content object (new uploads inherit the permissions of the Category they are uploaded into)resourceUsage
module to store the filesizecategories
module to insert the new object in the specified position in the Category it was uploaded intoaddObject
method of the particular plugin in question, to let the plugin take care of accepting the uploaded content item. Arguments passed include the metadata and the full name of the temporary file being used for the upload (e.g. "/tmp/phpE2qaT3") – since the upload process has not yet been completedaddObject
methods:uploader
module, and the upload is completed!viewer.php
) offer clickable icons to delete contentpluginHandler.php
pluginHandler.php
dispatches the deletion request to the method doDeleteContentItem
, provided by the class contentManager
(for now hosted in the file siteInitialization.php)