Advertisement
Vadorequest

Controller.ts

Feb 13th, 2014
323
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ///<reference path='./../lib/def/defLoader.d.ts'/>
  2.  
  3. export module Controllers {
  4.  
  5.     /**
  6.      *
  7.      * First, the super method is called.
  8.      * It calls a magic method such as __beforeIndex if the request was coming from an index method.
  9.      * If it doesn't found the origin, it calls directly __beforeEach method.
  10.      * If it does then the __beforeIndex will automatically call the __beforeEach in first place.
  11.      * Once all the __before magic methods are called, the custom method from the child is executed.
  12.      * The options object contains specific stuff that belongs to the controllers logic, I could have use the req but I prefer not.
  13.      *
  14.      * The public methods such as index/show/etc. are defined but send by default a 404 response if they are not override in the child class.
  15.      * They exists just to bind by default all these methods without take care if they exists or not.
  16.      */
  17.     export class Controller {
  18.  
  19.         /**
  20.          * Default theme to use by default.
  21.          */
  22.         private static _defaultTheme = 'ayolan';
  23.  
  24.         /**
  25.          * Relative path to a layout from a view.
  26.          */
  27.         private static _layoutRelativePath = '../_layouts/';
  28.  
  29.         /**
  30.          * Default layout to use by default.
  31.          */
  32.         private static _defaultLayout = 'default';
  33.  
  34.         /**
  35.          * Exported methods. Must be override by the childs to add custom methods.
  36.          */
  37.         public static exportedMethods: any = [];
  38.  
  39.         /**
  40.          * Theme used by the controller by default.
  41.          * Could be override by the user theme.
  42.          */
  43.         public static theme: string = Controller._defaultTheme;
  44.  
  45.         /**
  46.          * Theme used by the controller by default.
  47.          * Could be override by the user theme.
  48.          */
  49.         public static layout: string = Controller._defaultLayout;
  50.  
  51.         /**
  52.          * Exported methods by default.
  53.          * These methods will be accessible from internet.
  54.          */
  55.         private static _defaultExportedMethods: any = [
  56.             // Sails controller custom config.
  57.             '_config',
  58.  
  59.             // Default predefined controller methods.
  60.             'index',
  61.             'show',
  62.             'new',
  63.             'create',
  64.             'edit',
  65.             'update',
  66.             'destroy'
  67.         ];
  68.  
  69.         /**
  70.          * Overrides for the settings in `config/controllers.js`
  71.          * (specific to the controller where it's defined)
  72.          */
  73.         private static _config = {};
  74.  
  75.         /**
  76.          * Name of the folder located in /views/ that will contains the back office views.
  77.          */
  78.         private static _backofficeFolderName = 'dasboard';
  79.  
  80.         /**
  81.          **************************************************************************************************
  82.          **************************************** Static methods ******************************************
  83.          **************************************************************************************************
  84.          */
  85.  
  86.         /**
  87.          * Acts as a super workflow controller to automatically call events when it's possible.
  88.          * Used to call magic methods before the targeted methods is called.
  89.          * @param req       Request.
  90.          * @param res       Response.
  91.          * @param callback  Function to execute.
  92.          * @param options   Object that contains options.
  93.          *          controller  Controller      Child controller class. (static)
  94.          *
  95.          */
  96.         public static super(req, res, callback, options: any = {}){
  97.             // Extract information from the child.
  98.             options.controllerName = req.target.controller;
  99.             options.methodName = req.target.action;
  100.  
  101.             // Check that the dedicated method has a __before magic method in the current controller.
  102.             if((Controller._getCurrentController(options))['__before' + Controller._cleanMethodName(options.methodName)]){
  103.                 // Custom before method is available. Call it. Remove underscores by security. (Protected/private methods)
  104.                 (Controller._getCurrentController(options))['__before' + Controller._cleanMethodName(options.methodName)](req, res, callback, options);
  105.             }else{
  106.                 // By default, always call the global magic method.
  107.                 (Controller._getCurrentController(options))['__beforeEach'](req, res, callback, options);
  108.             }
  109.         }
  110.  
  111.         /**
  112.          * Methods which MUST BE OVERRIDE in ALL childs.
  113.          * Returns an object that contains all exported methods for the targeted child.
  114.          * @param child     The child controller class. (not an instance)
  115.          * @returns {*}
  116.          */
  117.         public static exports(child?: any): any{
  118.             if(!child){
  119.                 throw 'The exports method must be override in all Controller childs: ' + __filename;
  120.             }
  121.  
  122.             // Merge default array and custom array from child.
  123.             var methods: any = Controller._defaultExportedMethods.concat(child['exportedMethods']);
  124.             var exportedMethods: any = {};
  125.  
  126.             for(var i = 0; i < methods.length; i++){
  127.                 exportedMethods[methods[i]] = child[methods[i]];
  128.             }
  129.  
  130.             return exportedMethods;
  131.         }
  132.  
  133.         /**
  134.          * Default view renderer, manages basic data and stuff to always bind into the views.
  135.          * @param req           Request.
  136.          * @param res           Response.
  137.          * @param options   Specific options to render the view.
  138.          * @param view          View to load. Use the path controller/method by default.
  139.          */
  140.         public static renderView(req, res, options: any = {}, view: any = false){
  141.             // Bind default data.
  142.             options.date = new Date().getTime();
  143.             options.currentUser = options.currentUser || req.session.user;
  144.             options.translations = options.translations || require('./../data/translations.json').translations;
  145.             options.users = options.users || require('./../data/users.json').users;
  146.             options.theme = options.theme || Controller._getCurrentController(options).theme;
  147.             options._layoutFile = options.layout ? Controller._getLayout(options.layout) : Controller._getLayout();
  148.             options.controller = req.target.controller;
  149.             options.action = req.target.action;
  150.  
  151.             if(view === false){
  152.                 return res.view(options);
  153.             }else{
  154.                 return res.view(view, options);
  155.             }
  156.         }
  157.  
  158.         /**
  159.          * View renderer adapted for the back office part of the website.
  160.          * @param req           Request.
  161.          * @param res           Response.
  162.          * @param options   Specific options to render the view.
  163.          * @param view          View to load. Use the path controller/method by default.
  164.          */
  165.         public static renderViewBackoffice(req, res, options: any = {}, view: any = false){
  166.             if(view){
  167.                 // Custom path, just add the backoffice folder.
  168.                 view = Controller._backofficeFolderName + '/' + view;
  169.             }else{
  170.                 // No path, use the targets to know which view to call.
  171.                 view = req.target.controller.replace(Controller._backofficeFolderName, '') + '/' + req.target.action
  172.             }
  173.  
  174.             return Controller.renderView(req, res, options, view);
  175.         }
  176.  
  177.         /**
  178.          **************************************************************************************************
  179.          **************************************** Controller basic methods ********************************
  180.          **************************************************************************************************
  181.          */
  182.  
  183.         /**
  184.          * Displays the global content, displays several resources.
  185.          * This method is just to return a 404 error and explain the role.
  186.          * @param req       Request.
  187.          * @param res       Response.
  188.          * @param callback  Function to execute.
  189.          * @param options   Object that contains options.
  190.          */
  191.         public static index(req, res, callback, options: any = {}){
  192.             Controller.__beforeIndex(req, res, function(req, res, callback, options){
  193.                 res.notFound();
  194.             }, options)
  195.         }
  196.  
  197.         /**
  198.          * Show only one resource. (Focuses on one, not many)
  199.          * This method is just to return a 404 error and explain the role.
  200.          * @param req       Request.
  201.          * @param res       Response.
  202.          * @param callback  Function to execute.
  203.          * @param options   Object that contains options.
  204.          */
  205.         public static show(req, res, callback, options: any = {}){
  206.             Controller.__beforeShow(req, res, function(req, res, callback, options){
  207.                 res.notFound();
  208.             }, options)
  209.         }
  210.  
  211.         /**
  212.          * Display the content to create a new resource.
  213.          * This method is just to return a 404 error and explain the role.
  214.          * @param req       Request.
  215.          * @param res       Response.
  216.          * @param callback  Function to execute.
  217.          * @param options   Object that contains options.
  218.          */
  219.         public static new(req, res, callback, options: any = {}){
  220.             Controller.__beforeNew(req, res, function(req, res, callback, options){
  221.                 res.notFound();
  222.             }, options)
  223.         }
  224.  
  225.         /**
  226.          * Manage the request to create a new resource.
  227.          * Basically called from a "new" view.
  228.          * This method is just to return a 404 error and explain the role.
  229.          * @param req       Request.
  230.          * @param res       Response.
  231.          * @param callback  Function to execute.
  232.          * @param options   Object that contains options.
  233.          */
  234.         public static create(req, res, callback, options: any = {}){
  235.             Controller.__beforeCreate(req, res, function(req, res, callback, options){
  236.                 res.notFound();
  237.             }, options)
  238.         }
  239.  
  240.         /**
  241.          * Display the content to edit an existing resource.
  242.          * This method is just to return a 404 error and explain the role.
  243.          * @param req       Request.
  244.          * @param res       Response.
  245.          * @param callback  Function to execute.
  246.          * @param options   Object that contains options.
  247.          */
  248.         public static edit(req, res, callback, options: any = {}){
  249.             Controller.__beforeEdit(req, res, function(req, res, callback, options){
  250.                 res.notFound();
  251.             }, options)
  252.         }
  253.  
  254.         /**
  255.          * Manage the request to update an existing resource.
  256.          * Basically called from an "edit" view.
  257.          * This method is just to return a 404 error and explain the role.
  258.          * @param req       Request.
  259.          * @param res       Response.
  260.          * @param callback  Function to execute.
  261.          * @param options   Object that contains options.
  262.          */
  263.         public static update(req, res, callback, options: any = {}){
  264.             Controller.__beforeUpdate(req, res, function(req, res, callback, options){
  265.                 res.notFound();
  266.             }, options)
  267.         }
  268.  
  269.         /**
  270.          * Destroy a resource.
  271.          * This method is just to return a 404 error and explain the role.
  272.          * @param req       Request.
  273.          * @param res       Response.
  274.          * @param callback  Function to execute.
  275.          * @param options   Object that contains options.
  276.          */
  277.         public static destroy(req, res, callback, options: any = {}){
  278.             Controller.__beforeDestroy(req, res, function(req, res, callback, options){
  279.                 res.notFound();
  280.             }, options)
  281.         }
  282.  
  283.         /**
  284.          **************************************************************************************************
  285.          **************************************** Magic methods *******************************************
  286.          **************************************************************************************************
  287.          */
  288.  
  289.         /**
  290.          * Automatically triggered before each called method.
  291.          * @param req       Request.
  292.          * @param res       Response.
  293.          * @param callback  Function to execute.
  294.          * @param options   Object that contains options.
  295.          * @private
  296.          */
  297.         public static __beforeEach(req, res, callback, options: any = {}){
  298.             // Bind fake data.
  299.             if(!req.session.user){
  300.                 req.session.user = require('./../data/users.json').users[0];
  301.             }
  302.  
  303.             callback(req, res, options);
  304.  
  305.             // Add debug information.
  306.             dev(function(){
  307.                 // TODO Add file upload debug using req.files
  308.                 // TODO Add ip
  309.                 consoleDev('Url: ' + req.method + ' ' + req.baseUrl + req._parsedUrl.href, 'debug');
  310.                 consoleDev('Options: ' + JSON.stringify(options), 'debug');
  311.                 consoleDev('Route: ' + req.route.method + ' ' + req.path + ' (' + req.route.regexp + ')', 'debug');
  312.                 consoleDev('Cookies: ' + req.headers.cookie, 'debug');
  313.                 consoleDev('User agent: ' + req.headers['user-agent'], 'debug');
  314.                 consoleDev('Session: ' + JSON.stringify(req.session), 'debug');
  315.                 consoleDev('---------------------------------------', 'debug');
  316.             });
  317.         }
  318.  
  319.         /**
  320.          * Automatically triggered before all index methods are called.
  321.          * @param req       Request.
  322.          * @param res       Response.
  323.          * @param callback  Function to execute.
  324.          * @param options   Object that contains options.
  325.          * @private
  326.          */
  327.         public static __beforeIndex(req, res, callback, options: any = {}){
  328.             (Controller._getCurrentController(options)).__beforeEach(req, res, function(req, res, options){
  329.                 callback(req, res, options);
  330.             }, options);
  331.         }
  332.  
  333.         /**
  334.          * Automatically triggered before all show methods are called.
  335.          * @param req       Request.
  336.          * @param res       Response.
  337.          * @param callback  Function to execute.
  338.          * @param options   Object that contains options.
  339.          * @private
  340.          */
  341.         public static __beforeShow(req, res, callback, options: any = {}){
  342.             (Controller._getCurrentController(options)).__beforeEach(req, res, function(req, res, options){
  343.                 callback(req, res, options);
  344.             }, options);
  345.         }
  346.  
  347.         /**
  348.          * Automatically triggered before all new methods are called.
  349.          * @param req       Request.
  350.          * @param res       Response.
  351.          * @param callback  Function to execute.
  352.          * @param options   Object that contains options.
  353.          * @private
  354.          */
  355.         public static __beforeNew(req, res, callback, options: any = {}){
  356.             (Controller._getCurrentController(options)).__beforeEach(req, res, function(req, res, options){
  357.                 callback(req, res, options);
  358.             }, options);
  359.         }
  360.  
  361.         /**
  362.          * Automatically triggered before all create methods are called.
  363.          * @param req       Request.
  364.          * @param res       Response.
  365.          * @param callback  Function to execute.
  366.          * @param options   Object that contains options.
  367.          * @private
  368.          */
  369.         public static __beforeCreate(req, res, callback, options: any = {}){
  370.             (Controller._getCurrentController(options)).__beforeEach(req, res, function(req, res, options){
  371.                 callback(req, res, options);
  372.             }, options);
  373.         }
  374.  
  375.         /**
  376.          * Automatically triggered before all edit methods are called.
  377.          * @param req       Request.
  378.          * @param res       Response.
  379.          * @param callback  Function to execute.
  380.          * @param options   Object that contains options.
  381.          * @private
  382.          */
  383.         public static __beforeEdit(req, res, callback, options: any = {}){
  384.             (Controller._getCurrentController(options)).__beforeEach(req, res, function(req, res, options){
  385.                 callback(req, res, options);
  386.             }, options);
  387.         }
  388.  
  389.         /**
  390.          * Automatically triggered before all update methods are called.
  391.          * @param req       Request.
  392.          * @param res       Response.
  393.          * @param callback  Function to execute.
  394.          * @param options   Object that contains options.
  395.          * @private
  396.          */
  397.         public static __beforeUpdate(req, res, callback, options: any = {}){
  398.             (Controller._getCurrentController(options)).__beforeEach(req, res, function(req, res, options){
  399.                 callback(req, res, options);
  400.             }, options);
  401.         }
  402.  
  403.         /**
  404.          * Automatically triggered before all destroy methods are called.
  405.          * @param req       Request.
  406.          * @param res       Response.
  407.          * @param callback  Function to execute.
  408.          * @param options   Object that contains options.
  409.          * @private
  410.          */
  411.         public static __beforeDestroy(req, res, callback, options: any = {}){
  412.             (Controller._getCurrentController(options)).__beforeEach(req, res, function(req, res, options){
  413.                 callback(req, res, options);
  414.             }, options);
  415.         }
  416.  
  417.         /**
  418.          **************************************************************************************************
  419.          **************************************** Private methods *****************************************
  420.          **************************************************************************************************
  421.          */
  422.  
  423.         /**
  424.          * Based on the option, used to determinate which controller class use, a child if exists or the parent.
  425.          * @param options   See args explained at Controller.super
  426.          * @returns {*}
  427.          * @private
  428.          */
  429.         private static _getCurrentController(options): any{
  430.             if(options.controller){
  431.                 return options.controller;
  432.             }else{
  433.                 return Controller;
  434.             }
  435.         }
  436.  
  437.         /**
  438.          * Clean the name of a method to avoid anything bad.
  439.          * @param method
  440.          * @returns {*}
  441.          * @private
  442.          */
  443.         private static _cleanMethodName(method): string {
  444.             return ucfirst(method.replace('_', ''));
  445.         }
  446.  
  447.         /**
  448.          * Should return the layout to use without have to take care of the relative path, it should be managed by the controller.
  449.          * @param layout
  450.          * @returns {string}
  451.          * @private
  452.          */
  453.         private static _getLayout(layout = Controller._defaultLayout){
  454.             return Controller._layoutRelativePath + layout;
  455.         }
  456.     }
  457. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement