SuiteCRM developing a custom module - module

I am trying to build a custom module based on the 'basic' template, with extra fields without using the module builder.
I have looked trough the SugarCRM 6.5 documentation, bought the book SuiteCRM for Developers and looked trough the sources of existing modules, but I still can not figure out how to put a working module together.
Does a minimal module template exists anywhere? What I am looking for is a fully working module with one extra field, which can be deployed on a SuiteCRM instance. I can take it from there.

There's no minimal module template that I know of, you may want to consider creating a test module through module builder and exporting that to see what the parts are.
Usually though modules have the following files. Example uses the module ABC_Sport.
custom/Extension/application/Ext/Include/ABC_Sport.php
This adds the module to the module list and adds the beans. I.e.
$beanList['ABC_Sport'] = 'ABC_Sport';
$beanFiles['ABC_Sport'] = 'modules/ABC_Sport/ABC_Sport.php';
$moduleList[] = 'ABC_Sport';
custom/Extension/application/Ext/Include/en_us.ABC_Sport.php
(Note you may want to add files for different languages).
Next up you'll need to create the bean file in
modules/ABC_Sport/ABC_Sport.php
and the vardefs in
modules/ABC_Sport/vardefs.php
I'm not totally sure if the metadata files are required or not but you'll also likely want to add the editviewdefs,detailviewdefs and listviewdefs.

Related

Xquery extracting property values from .properties file

I am currently trying to extract property values from my properties file, but am running into some problems. I can't test this in ML query console, because the properties file doesn't exist there. I am currently trying to grab the values of the file like this
let $port := #{#properties["ml.properties-name"]}
I've also looked at
xdmp:document-get-properties(
$uri as xs:string,
$property as xs:QName
however that is limited to .xml files I believe. Does anyone have a way/work-around of accessing these values? I can't seem to find one I've looked at some documentation on Marklogic's website, but can't seem to get anything to work. The way I was accessing before was in ruby, through monkey-patching allowing me to access those private fields.The problem with that is the ruby script I call is only called once, while my .xqy file is ran every minute that sends args to another function. I need to access those args from the properties file, right now I just have them hard-coded in. Any thoughts?
Thanks
You cannot access deployment properties like that, but you can pass them along with deployment. If you create a new REST app with latest Roxy, you should get a copy of this config.xqy added to src/config/:
https://github.com/marklogic-community/roxy/blob/master/deploy/sample/custom-config.xqy
That file is treated specially when deployed to the modules database. Properties references are replaced inside there. In your case, add another variable, and give it a string value following the #ml.xyz pattern:
declare variable $c:port := "#ml.property-name";
You can then import the config lib, and use it in your code.
These so-called Deployer Substitutions are described in more detail on the Roxy wiki:
https://github.com/marklogic-community/roxy/wiki/Deployer-Substitutions

What is the difference between plugin and modules in Zend?

If I download a chat software on word press, it is called a Plugin. In Zend Framework it's called a Module, but there is also plugin's for Controllers.
What's the difference between modules and plugins in Zend?
A module in zf2 is similar to a plugin in wordpress yes! They are a collection of different classes that can be loaded into a project and allow either for reuse of generic code in other projects (this would be using composer in zf2) or modules can simply be used as groupings for similar code in a project.
zf2 is itself modular (I could just load some of the modules in my project, they are designed to work standalone) but lets not do that here
composer.json
{
"name": "myApp",
"require": {
"php": ">=5.3.3",
"zendframework/zendframework": "~2.3.0",
"zf-commons/zfc-twig": "dev-1.2rc1"
},
"autoload": {
"psr-0": {
"Application": "module/Application/src/"
}
}
}
providing composer is installed I can just run:
composer update
from the command line. If you haven't had much experience with composer, the docs ain't bad https://getcomposer.org/doc/ but it is a must have for zf2 development!
Then in the root of your app you can then add to config.application.config.php your modules
return array(
'modules' => array(
'zfTwig',
'MyCustomModule',
),
}
Now these modules are available in your project. For more information see
http://www.michaelgallego.fr/blog/2013/01/21/some-tips-to-write-better-zend-framework-2-modules/
and
http://mwop.net/blog/267-Getting-started-writing-ZF2-modules.html
You can also add modules yourself at the application level (as I said previously these are more for grouping features or whatever you fancy together).
You can use this to help build your personal modules
https://github.com/zendframework/ZendSkeletonModule
Just place the ZendSkeletonModule in the module folder of your zf2 app and update all the namespaces and the root folder of the module to match. In the case of the application.config.php I have above you would rename it all "MyCustomModule".
A controller plugin is something quite different, they are just a class which is registered to be injected into a controller basically
They can be called in your controllers to perform certain tasks.
The FlashMessenger plugin for example allows you to register a message in the flash messenger within your controller that will be displayed on the next page load.
From the zf2 docs
$this->flashMessenger()->addMessage('You are now logged in.');
return $this->redirect()->toRoute('user-success');
see http://framework.zend.com/manual/2.0/en/modules/zend.mvc.plugins.html for more detail
Modules
A module is a self contained collection of code that provides similar functionality within an application.
This means modules can be anything you desire them to be (one file or your whole application!).
'Modules' are not new terminology in ZF2; "Modular Programming" has been around for a long time. By having logical groups of code functionality it will promote code reuse and the 'open close principle'.
Modules in ZF2
Modules are first class citizens within Zend Framework 2; this means that the framework was designed specifically for the purpose of being able to add and remove modules with ease.
There are many examples of ZF2 modules online - Most of which would require minor configuration changes and you can begin using them (code reuse!)
Plugins
Again a generic term that will have different meanings in different frameworks. You may have heard of 'pluggable software', this answer summaries it nicely.
[A design for when] you want a system to work in straightforward and predictable ways, with very specific points of variation.
The 'points of variation' are areas of your code that are likely to require changes or different logic. A system that allows for external sources to be injected without the base code being modified is thought to be 'plugable'.
Plugins in ZF2
A 'Plugin' in ZF2 is actually known as a 'Controller plugin'
They are classes designed to add functionality to Controllers (any class extending Zend\Mvc\Controller\AbstractActionController), without the need to extend the controller class.
Some examples of this are the Zend\Mvc\Controller\Plugin\FlashMessenger which allows you to add a message to session and display it on the reloaded page. This can be reused in all your controllers without needing to modify them.

Application modules with Pyramid

I'm creating a workflow app with pyramid and i'm searching how to make the application modulable : meaning create a core app with sqlalchemy models, base forms with wtforms, and some base templates with mako.
The basic structure of the "Core" app is:
App_Core/core.ini
/setup.py
/...
/App_Core/
/__init__.py
/models.py
/forms.py
/utils.py
/templates/
/templates/base.mako...
/static/
/static/staticfiles...
My goal is to create 1 application per workflow which will be included in the Core app : it seems possible to do that via the includeme function provided with pyramid.
I want to include each workflow via the core.ini file, for example:
pyramid.includes =
workflow_app1
workflow_app2
workflow_app3
...
I defined an new app called workflow_app1 with the following structure:
worflow_app1/
/setup.py
/...
/workflow_app1/
/__init__.py
/models.py
/forms.py
/views.py
/templates/
/templates/workflow_app1.mako
/...
And the _init_.py file will contain the includeme function and will define new routes:
def includeme(config):
config.add_route('route1', '/route1/')
config.add_route('route2', '/route2/')
config.scan()
When i'm writing a view for the worflow_app1, i'm rendering to a template included with that app, but when i'm calling it from the core app, it can't render the template and gives the following error:
TopLevelLookupException: Cant locate template for uri 'workflow-app1.mako'
This error quite logical cause the mako.directories directive is given with the path App_Core_PATH/templates so my template should be in the same folder.
Question1:
Is it possible to make mako searching in each folder of modules the wanted templates?
Question2:
Is it possible to make the workflow-app1.mako inheriting of the base.mako from the core app?
Thanks by advance for your answer.
The solution that I would recommend is switching to asset specs for your templates. They are explicit, allow overriding, and provide better control over your template hierarchy. This means that you would stop using mako.directories and instead use 'workflow_app1:templates/workflow_app1.mako' in your inherits or include or renderer arguments. Given this, it's obvious that you can inherit from your base.mako in your core app, whereas managing the mako.directories option is more difficult.
If you're deadset on mako.directories then you can add a line to it every time you add a package to pyramid.includes.
mako.directores =
App_Core:templates
workflow_app1:templates
workflow_app2:templates
Another option is to switch to jinja2, as its plugin has the ability to add search paths after the fact. Thus your included modules can config.add_jinja2_search_path(...) throwing themselves into the lookup order. Pyramid's mako integration does not offer this option right now.

EntLib 5 Wrap Handler Message Localization

I have been asked, at very short notice of course, to implement exception logging to the Windows Application event Log in one of our products (vb.Net, framework 3.5, WinForms) using EntLib 5. In and of itself this is fine - I can get that working. However, this is for a client who wants messages in Chinese. Certain parts of the app have language resource files and I found a couple of sentences in my MS EntLib Developers Guide book which suggested that I could use an external resource to provide a localised 'friendly' message in a wrap handler within the Exception Handling Block.
Unfortunately there was no mention of how to actually achieve this but it seemed straightforward enough. I added a new resource to a resx file which lives at the project level for the project which is common to all areas of the application and re-built to project so that the satellite assemblies were built. I then specified the name of the resource in the 'Message Resource Name' field within the EntLib configuration console. the problem arises when I try and specify the 'Message Resource Type'.
I clicked on the search button and found the satellite assembly I needed, but it did not get added to the list of loaded assemblies and therefore I couldn't select it. The problem is that none of the places where I've seen this feature mentioned actually demonstrate how to get it working so I'm not sure where I'm going wrong. The search for the assembly will only let me select a dll or exe so I assume I am supposed to reference the satellite assembly somehow but how do I do this if it won't add it to the list of loaded assemblies?
One point to note is that we have a main executable which then calls numerous class libraries to load areas of functionality as required, and the config file we use throughout is the one which belongs to the main executable. Is it the case that you can only use satellite assemblies which are related to the assembly that the config file belongs to?
I haven't yet fully utilized this feature yet but just something to check, are you using the fully qualified name of the assembly?
EDIT: A potentially applicable link - http://entlib.codeplex.com/discussions/67460

getting an embedded resource in a single dll made up of multiple class libraries

my solution has multiple projects and in one of them I have the code to get the embedded resource (an xml file) from another project. All this works fine when all the projects are seperate. However when all the class libraries are embedded into a single dll, the code to get the resource file does not work i.e. it cannot get the emebedded resource.
I was wondering if the references to the emebedded resource get mixed up when they are combined together in a single dll??
I use the method Assembly.GetCallingAssembly().GetManifestResourceStream("namespace..filename");
I would not use Assembly.GetCallingAssembly(). I would use typeof(SomeClassNextToXmlFile).Assembly that way if you are calling the dll with the embedded resource from a exe file it won't go looking in the exe for the resource. Also you may want to try using Reflector and make sure the resource you are looking for is where you think it is.