{"id":565,"date":"2016-09-20T08:14:04","date_gmt":"2016-09-20T08:14:04","guid":{"rendered":"http:\/\/myprojects.advchaweb.com\/?p=565"},"modified":"2020-11-22T14:39:59","modified_gmt":"2020-11-22T14:39:59","slug":"osclass-tips-and-tricks","status":"publish","type":"post","link":"https:\/\/myprojects.advchaweb.com\/index.php\/2016\/09\/20\/osclass-tips-and-tricks\/","title":{"rendered":"OSClass Tips and Tricks"},"content":{"rendered":"<p>Create a plugin to remove ad\/listing spam. currently the item list only can show 100 ad max. create a plugin so it can remove as many ad as we want???<!--more--><\/p>\n<p>How to delete more than 100 listing on the &#8216;manage listing&#8217; page on the admin page?<br \/>\nSOLUTION: (NOT COMPLETED YET) need to learn the code in \/oc-admin\/items.php<\/p>\n<pre class=\"lang:default decode:true\">...\r\ncase 'delete_all':\r\n    $id = Params::getParam('id');\r\n    $success = false;\r\n\r\n    if($id) {\r\n        $numSuccess = 0;\r\n        foreach($id as $i) {\r\n            if ($i) {\r\n                $item = $this-&gt;itemManager-&gt;findByPrimaryKey($i);\r\n                $success = $mItems-&gt;delete($item['s_secret'], $item['pk_i_id']);\r\n                if($success) {\r\n                    $numSuccess++;\r\n                }\r\n            }\r\n        }\r\n        osc_add_flash_ok_message( sprintf(_mn('%d listing has been deleted', '%d listings have been deleted', $numSuccess), $numSuccess), 'admin');\r\n    }\r\n...<\/pre>\n<p>but\u00a0Params::getParam(&#8216;id&#8217;) only can see the &#8216;id&#8217; on the checked values on the manage list. even though the max listing on the list only 100. so how to delete more than that??? learn again this line:<\/p>\n<pre class=\"lang:default decode:true \">$mItems-&gt;delete($item['s_secret'], $item['pk_i_id']);<\/pre>\n<p>OK. now how to get the list all of the item id??? or from an item id to another item id??? HOMEWORK!!!<br \/>\nOK. I can do this without use the admin listing page. but instead of creating a new plugin (it&#8217;d need more work), I use another plugin (use the functions, model, etc). its real esatet plugin. First of all, in\u00a0\/plugins\/realestate_attributes\/ModelRealEstate.php file, I added two functions. The first to call the item table and the second to populate the specific item data based on our criteria.<\/p>\n<pre class=\"lang:default decode:true \">public function getTable_Item()\r\n{\r\n    return DB_TABLE_PREFIX.'t_item';\r\n}\r\n\r\npublic function getSpecificItem()\r\n{\r\n    $result = $this-&gt;dao-&gt;query( sprintf(\"SELECT pk_i_id FROM %s WHERE pk_i_id &lt; 19812\", $this-&gt;getTable_Item()) ) ;\r\n    return $result-&gt;result() ;\r\n}<\/pre>\n<p>Then in\u00a0\/plugins\/realestate_attributes\/conf.php file, we call those function at the beginning.<\/p>\n<pre class=\"lang:default decode:true\">$specific_item = ModelRealEstate::newInstance()-&gt;getSpecificItem() ;\r\nforeach ($specific_item as $s) {\r\n    $mItems  = new ItemActions( true );\r\n    $item = Item::newInstance()-&gt;findByPrimaryKey($s['pk_i_id']);\r\n    $mItems-&gt;delete($item['s_secret'], $item['pk_i_id']);\r\n}<\/pre>\n<p>We can run it on our browser with url http:\/\/localhost\/&#8230;\/oc-admin\/index.php?page=plugins&amp;action=renderplugin&amp;file=realestate_attributes\/conf.php. But becareful to use this script. If we have many records that need to be deleted, it&#8217;d take many time and computer\/server resource. sometimes I got a message:\u00a0&#8220;<b>Fatal error<\/b>: Maximum execution time of 30 seconds exceeded in <b>\/home\/&#8230;\/oc-includes\/osclass\/model\/Item.php<\/b> on line <b>128<\/b>&#8220;. So check your server setting! Do you have more elegant solutions?<\/p>\n<p><span style=\"background-color: #ff6600;\">How to create multi step posting ad page?<br \/>\n<span style=\"background-color: #000000;\">currently multi step can&#8217;t move back to the previous step (http:\/\/localhost\/works\/kokopage\/index.php?page=item&amp;action=item_add). I have to refresh it.<\/span><\/span> but can use &#8216;previous&#8217; button?<br \/>\nThe Steps (previous and next) on each page are showed up by helping of jquery. the jquery script is reside in \/themes\/classer\/js\/FormToWizard.js<\/p>\n<pre class=\"lang:default decode:true \">\/* Created by jankoatwarpspeed.com *\/\r\n\r\n(function($) {\r\n    $.fn.formToWizard = function(options) {\r\n        options = $.extend({  \r\n            submitButton: \"\" \r\n        }, options); \r\n        \r\n        var element = this;\r\n\r\n        var steps = $(element).find(\"fieldset\");\r\n        var count = steps.size();\r\n        var submmitButtonName = \"#\" + options.submitButton;\r\n        $(submmitButtonName).hide();\r\n\r\n        \/\/ 2\r\n        $(element).before(\"&lt;ul id='steps'&gt;&lt;\/ul&gt;\");\r\n\r\n        steps.each(function(i) {\r\n            $(this).wrap(\"&lt;div id='step\" + i + \"'&gt;&lt;\/div&gt;\");\r\n            $(this).append(\"&lt;p id='step\" + i + \"commands'&gt;&lt;\/p&gt;\");\r\n\r\n            \/\/ 2\r\n            var name = $(this).find(\"h2\").html();\r\n            $(\"#steps\").append(\"&lt;li id='stepDesc\" + i + \"'&gt;Step \" + (i + 1) + \"&lt;span&gt;\" + name + \"&lt;\/span&gt;&lt;\/li&gt;\");\r\n\r\n            if (i == 0) {\r\n                createNextButton(i);\r\n                selectStep(i);\r\n            }\r\n            else if (i == count - 1) {\r\n                $(\"#step\" + i).hide();\r\n                createPrevButton(i);\r\n                createPreviewButton(i);\r\n            }\r\n            else {\r\n                $(\"#step\" + i).hide();\r\n                createPrevButton(i);\r\n                createNextButton(i);\r\n            }\r\n        });\r\n\r\n        function createPrevButton(i) {\r\n            var stepName = \"step\" + i;\r\n            $(\"#\" + stepName + \"commands\").append(\"&lt;a href='#' id='\" + stepName + \"Prev' class='prev'&gt; Back&lt;\/a&gt;\");\r\n\r\n            $(\"#\" + stepName + \"Prev\").bind(\"click\", function(e) {\r\n                $(\"#\" + stepName).hide();\r\n                $(\"#step\" + (i - 1)).show();\r\n                $(submmitButtonName).hide();\r\n                selectStep(i - 1);\r\n            });\r\n        }\r\n\r\n        function createNextButton(i) {\r\n            var stepName = \"step\" + i;\r\n            $(\"#\" + stepName + \"commands\").append(\"&lt;a href='#' id='\" + stepName + \"Next' class='next'&gt;Next &lt;\/a&gt;\");\r\n\r\n            $(\"#\" + stepName + \"Next\").bind(\"click\", function(e) {\r\n                $(\"#\" + stepName).hide();\r\n                $(\"#step\" + (i + 1)).show();\r\n                if (i + 2 == count)\r\n                    $(submmitButtonName).show();\r\n                selectStep(i + 1);\r\n            });\r\n        }\r\n\r\n        function createPreviewButton(i) {\r\n            var stepName = \"step\" + i;\r\n            $(\"#\" + stepName + \"commands\").append(\"&lt;a href='#' id='\" + stepName + \"Next' class='next'&gt;Preview Ad &lt;\/a&gt;\");\r\n            \r\n            $(\"#\" + stepName + \"Next\").bind(\"click\", function(e) {\r\n                $(\"form#item-post\").submit();\r\n            });\r\n        }\r\n\r\n        function selectStep(i) {\r\n            $(\"#steps li\").removeClass(\"current\");\r\n            $(\"#stepDesc\" + i).addClass(\"current\");\r\n        }\r\n\r\n    }\r\n})(jQuery); \r\n<\/pre>\n<p>Then call the script on \/themes\/classer\/item-post.php like this<\/p>\n<pre class=\"lang:default decode:true \">&lt;script type=\"text\/javascript\"&gt;\r\n    $(document).ready(function(){\r\n        $(\"#postingitem\").formToWizard({ submitButton: 'SaveAccount' })\r\n    });\r\n&lt;\/script&gt;<\/pre>\n<p>OSCLASS TIPS &amp; TRICKS<br \/>\n1. show warning and error on page -&gt; Put define(&#8216;OSC_DEBUG&#8217;, true) ; in config.php<br \/>\n2. show sql query on page -&gt; Put define(&#8216;OSC_DEBUG_DB&#8217;, true) ; in config.php<br \/>\n3. Change item url from http:\/\/localhost\/Projects\/motobroker\/sedans\/auction-1_i60<br \/>\nto http:\/\/localhost\/Projects\/motobroker\/victoria\/airport-west\/sedans\/auction-1_i60 (incluided region and city), pls do this (hard code) :<br \/>\na. edit oc_t_preference table and find &#8216;rewrite_item_url&#8217;. then change from {CATEGORIES}\/{ITEM_TITLE}_i{ITEM_ID}<br \/>\nto {ITEM_REGION}\/{ITEM_CITY}\/{CATEGORIES}\/{ITEM_TITLE}_i{ITEM_ID}<br \/>\nNOTE: We can&#8217;t just use {ITEM_REGION}\/{ITEM_CITY}\/{CATEGORIES}\/{ITEM_TITLE} . it&#8217;d display 404 page. we must add &#8216;_i{ITEM_ID}&#8217; at the end<br \/>\nb. find and edit function &#8216;osc_item_url_from_item&#8217; in \/oc-includes\/osclass\/helpers\/hDefines.php. add the region part :<br \/>\n$url = str_replace(&#8216;{ITEM_REGION}&#8217;, osc_sanitizeString($item[&#8216;s_region&#8217;]), $url);<br \/>\nso it&#8217;ll be<br \/>\nfunction osc_item_url_from_item($item, $locale = &#8221;)<br \/>\n{<br \/>\nif ( osc_rewrite_enabled() ) {<br \/>\n$url = osc_get_preference(&#8216;rewrite_item_url&#8217;);<br \/>\nif( preg_match(&#8216;|{CATEGORIES}|&#8217;, $url) ) {<br \/>\n$sanitized_categories = array();<br \/>\n$cat = Category::newInstance()-&gt;hierarchy($item[&#8216;fk_i_category_id&#8217;]);<br \/>\nfor ($i = (count($cat)); $i &gt; 0; $i&#8211;) {<br \/>\n$sanitized_categories[] = $cat[$i &#8211; 1][&#8216;s_slug&#8217;];<br \/>\n}<br \/>\n$url = str_replace(&#8216;{CATEGORIES}&#8217;, implode(&#8220;\/&#8221;, $sanitized_categories), $url);<br \/>\n}<br \/>\n$url = str_replace(&#8216;{ITEM_ID}&#8217;, osc_sanitizeString($item[&#8216;pk_i_id&#8217;]), $url);<br \/>\n$url = str_replace(&#8216;{ITEM_REGION}&#8217;, osc_sanitizeString($item[&#8216;s_region&#8217;]), $url);<br \/>\n$url = str_replace(&#8216;{ITEM_CITY}&#8217;, osc_sanitizeString($item[&#8216;s_city&#8217;]), $url);<br \/>\n$url = str_replace(&#8216;{ITEM_TITLE}&#8217;, osc_sanitizeString($item[&#8216;s_title&#8217;]), $url);<br \/>\n$url = str_replace(&#8216;?&#8217;, &#8221;, $url);<br \/>\nif($locale!=&#8221;) {<br \/>\n$path = osc_base_url().$locale.&#8221;\/&#8221;.$url;<br \/>\n} else {<br \/>\n$path = osc_base_url().$url;<br \/>\n}<br \/>\n} else {<br \/>\n$path = osc_item_url_ns($item[&#8216;pk_i_id&#8217;], $locale);<br \/>\n}<br \/>\nreturn $path;<br \/>\n}<\/p>\n<p>4. Get static page url : If we want to get an url of the static\/customized page, pls do like this (http:\/\/forums.osclass.org\/general-help\/get-url-of-a-page\/):<br \/>\n&lt;?php osc_get_static_page(&#8216;page_name&#8217;); ?&gt;<br \/>\n&lt;a href=&#8221;&lt;? php echo osc_static_page_url(); ?&gt;&#8221;&gt;Page Title&lt;\/a&gt;<\/p>\n<p>5. How to find out if this the admin page or not?<br \/>\nPls use:\u00a0\u00a0\u00a0 if( OC_ADMIN ) {<\/p>\n<p>5. How to send\/flash message?<br \/>\nPls use like this (before the redirection):<br \/>\nosc_add_flash_ok_message(__(&#8216;Killer form deleted correctly&#8217;, &#8216;jobboard&#8217;), &#8216;admin&#8217;); \/\/success\/ok message<br \/>\nosc_add_flash_info_message(__(&#8216;Killer form deleted correctly&#8217;, &#8216;jobboard&#8217;), &#8216;admin&#8217;); \/\/info\/notif message<br \/>\nosc_add_flash_message(__(&#8216;Problems tring to remove killer question form. Try it again.&#8217;, &#8216;jobboard&#8217;), &#8216;admin&#8217;);\/\/errro message<br \/>\nosc_add_flash_error_message(__(&#8220;Name is required&#8221;, &#8216;jobboard&#8217;));\/\/error message<br \/>\nFor the redirection, pls use:<br \/>\nosc_redirect_to(osc_admin_render_plugin_url(&#8220;jobboard\/manage_killer.php&#8221;)); \/\/sometime return error\/warning<br \/>\njob_js_redirect_to(osc_admin_render_plugin_url(&#8220;jobboard\/manage_killer.php&#8221;)); \/\/sometime return error\/warning<br \/>\nheader(&#8216;Location: &#8216; . osc_admin_render_plugin_url(&#8220;jobboard\/people.php&#8221;)); exit;\/\/usually success<\/p>\n<p>6. How to load the classes in the plugin? especially for loading MVC (model, view and controller) class (no controller here)<br \/>\npls do like this (in plugin index.php): ref: \/osclass_plugin_test\/oc-content\/plugins\/plugin-jobboard-master\/index.php<\/p>\n<p>define(&#8216;JOBBOARD_PATH&#8217;, dirname(__FILE__) . &#8216;\/&#8217;);<br \/>\ndefine(&#8216;JOBBOARD_VIEWS&#8217;, JOBBOARD_PATH . &#8216;views\/&#8217;);<\/p>\n<p>require_once(JOBBOARD_PATH . &#8216;model\/ModelJB.php&#8217;);<br \/>\nrequire_once(JOBBOARD_PATH . &#8216;model\/ModelKQ.php&#8217;);<br \/>\n&#8230;<\/p>\n<p>7. Put all actions (hooks) in a class<br \/>\nusually hooks reside in index.php of plugins. but here we can put them in a class and call it like this:<br \/>\n\/osclass_plugin_test\/oc-content\/plugins\/plugin-jobboard-master\/index.php:<br \/>\ndefine(&#8216;JOBBOARD_PATH&#8217;, dirname(__FILE__) . &#8216;\/&#8217;);<br \/>\ndefine(&#8216;JOBBOARD_VIEWS&#8217;, JOBBOARD_PATH . &#8216;views\/&#8217;);<\/p>\n<p>&#8230;<br \/>\nrequire_once(JOBBOARD_PATH . &#8216;class\/JobboardListingActions.php&#8217;);<br \/>\n&#8230;<\/p>\n<p>\/\/ init classes<br \/>\n&#8230;<br \/>\n$jb_listing_actions = new JobboardListingActions();<br \/>\n&#8230;<\/p>\n<p>\/osclass_plugin_test\/oc-content\/plugins\/plugin-jobboard-master\/class\/JobboardListingActions.php:<br \/>\nclass JobboardListingActions<br \/>\n{<br \/>\npublic function __construct() {<br \/>\n\/\/ add\/add-post<br \/>\nosc_add_hook(&#8216;item_form&#8217;,\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 array(&amp;$this, &#8216;jobboard_form&#8217;) );<br \/>\nosc_add_hook(&#8216;posted_item&#8217;,\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 array(&amp;$this, &#8216;jobboard_form_post&#8217;) );<br \/>\n&#8230;<br \/>\n}<\/p>\n<p>function jobboard_form($catID = null) {<br \/>\n&#8230;<br \/>\n}<br \/>\n}<br \/>\nHere we must use a reference (&amp;) to return the callback values like this: array(&amp;$this, &#8216;jobboard_form&#8217;) )<\/p>\n<p>8. how to create\/display a toolbar menu in admin dashboard?<br \/>\nwe can put them in a class and call it like this:<br \/>\n\/osclass_plugin_test\/oc-content\/plugins\/plugin-jobboard-master\/index.php:<br \/>\ndefine(&#8216;JOBBOARD_PATH&#8217;, dirname(__FILE__) . &#8216;\/&#8217;);<br \/>\ndefine(&#8216;JOBBOARD_VIEWS&#8217;, JOBBOARD_PATH . &#8216;views\/&#8217;);<\/p>\n<p>&#8230;<br \/>\nif( OC_ADMIN ) {<br \/>\n&#8230;<br \/>\nrequire_once(JOBBOARD_PATH . &#8216;class\/JobboardAdminMenu.php&#8217;);<br \/>\n&#8230;<\/p>\n<p>\/\/ init oc-admin classes<br \/>\n&#8230;<br \/>\n$jb_admin_menu\u00a0\u00a0\u00a0\u00a0\u00a0 = new JobboardAdminMenu();<br \/>\n&#8230;<br \/>\n}<br \/>\n&#8230;<\/p>\n<p>\/osclass_plugin_test\/oc-content\/plugins\/plugin-jobboard-master\/class\/JobboardAdminMenu.php:<br \/>\nclass JobboardAdminMenu<br \/>\n{<br \/>\npublic function __construct() {<br \/>\nosc_add_hook(&#8216;admin_menu_init&#8217;, array(&amp;$this, &#8216;init&#8217;));<br \/>\n}<\/p>\n<p>\/**<br \/>\n* Add new menu entries<br \/>\n*\/<br \/>\npublic function init() {<br \/>\nosc_add_admin_menu_page(<br \/>\n__(&#8216;Jobboard&#8217;, &#8216;jobboard&#8217;),<br \/>\nosc_admin_render_plugin_url(&#8220;jobboard\/dashboard.php&#8221;),<br \/>\n&#8216;jobboard&#8217;,<br \/>\n&#8216;moderator&#8217;<br \/>\n);<\/p>\n<p>osc_add_admin_submenu_page(<br \/>\n&#8216;jobboard&#8217;,<br \/>\n__(&#8216;Dashboard&#8217;, &#8216;jobboard&#8217;),<br \/>\nosc_admin_render_plugin_url(&#8220;jobboard\/dashboard.php&#8221;),<br \/>\n&#8216;jobboard_dash&#8217;,<br \/>\n&#8216;moderator&#8217;<br \/>\n);<\/p>\n<p>osc_add_admin_submenu_page(<br \/>\n&#8216;jobboard&#8217;,<br \/>\n__(&#8216;Applicants&#8217;, &#8216;jobboard&#8217;),<br \/>\nosc_admin_render_plugin_url(&#8220;jobboard\/people.php&#8221;),<br \/>\n&#8216;jobboard_people&#8217;,<br \/>\n&#8216;moderator&#8217;<br \/>\n);<\/p>\n<p>\/\/ killer questions menu<br \/>\nosc_add_admin_submenu_page(<br \/>\n&#8216;jobboard&#8217;,<br \/>\n__(&#8216;Killer Questions&#8217;, &#8216;jobboard&#8217;),<br \/>\nosc_admin_render_plugin_url(&#8220;jobboard\/manage_killer.php&#8221;),<br \/>\n&#8216;jobboard_killer&#8217;,<br \/>\n&#8216;moderator&#8217;<br \/>\n);<\/p>\n<p>osc_add_admin_submenu_page(<br \/>\n&#8216;jobboard&#8217;,<br \/>\n__(&#8216;Download resumes&#8217;, &#8216;jobboard&#8217;),<br \/>\nosc_admin_render_plugin_url(&#8220;jobboard\/resume_download.php&#8221;),<br \/>\n&#8216;jobboard_resumedownload&#8217;,<br \/>\n&#8216;moderator&#8217;<br \/>\n);<\/p>\n<p>osc_add_admin_submenu_page(<br \/>\n&#8216;jobboard&#8217;,<br \/>\n__(&#8216;Default locations&#8217;, &#8216;jobboard&#8217;),<br \/>\nosc_admin_render_plugin_url(&#8220;jobboard\/admin\/settings.php&#8221;),<br \/>\n&#8216;jobboard_locations&#8217;,<br \/>\n&#8216;moderator&#8217;<br \/>\n);<br \/>\n}<\/p>\n<p>Here we use &#8216;osc_add_admin_menu_page&#8217; to create the toolbar and &#8216;osc_add_admin_submenu_page&#8217; to create the sub-toolbar<\/p>\n<p>9. We better use &#8216;Cookie&#8217; to send a value just from a page to another page instead of &#8216;Session&#8217;. in the another page we can use ????? With &#8216;cookies&#8217; we can set and store how long (day, month or year) the values would last but &#8216;session&#8217; only for current values (in a day)<br \/>\nref:\/osclass_plugin_test\/oc-content\/plugins\/plugin-jobboard-master\/index.php:<br \/>\n&#8230;<br \/>\nif( Params::getParam(&#8216;iDisplayLength&#8217;) != &#8221; ) {<br \/>\nCookie::newInstance()-&gt;push(&#8216;applicants_iDisplayLength&#8217;, Params::getParam(&#8216;iDisplayLength&#8217;));<br \/>\nCookie::newInstance()-&gt;set();<br \/>\n} else {<br \/>\n\/\/ set a default value if it&#8217;s set in the cookie<br \/>\nif( Cookie::newInstance()-&gt;get_value(&#8216;applicants_iDisplayLength&#8217;) != &#8221; ) {<br \/>\nParams::setParam(&#8216;iDisplayLength&#8217;, Cookie::newInstance()-&gt;get_value(&#8216;applicants_iDisplayLength&#8217;));<br \/>\n} else {<br \/>\nParams::setParam(&#8216;iDisplayLength&#8217;, 10);<br \/>\n}<br \/>\n}<\/p>\n<p>9. Is it better to use &#8216;osc_get_preference&#8217; and &#8216;osc_set_preference&#8217;??<br \/>\nIts better to use those functions to store\/get values for the plugins settings<br \/>\nexample:<br \/>\nref:\/osclass_plugin_test\/oc-content\/plugins\/plugin-jobboard-master\/people.php:<br \/>\n$feature = (int) osc_get_preference(&#8216;new_feature_add_applicant&#8217;, &#8216;jobboard_plugin&#8217;);<br \/>\nif( $feature === 0 ) {<br \/>\nosc_set_preference(&#8216;new_feature_add_applicant&#8217;, 1, &#8216;jobboard_plugin&#8217;);<br \/>\n}<\/p>\n<p>10. For what and why use View::newInstance()-&gt;_exportVariableToView(&#8216;items&#8217;, $aItems); ??<br \/>\nThe code will export\/spit out items with some &#8216;items helper&#8217; function on &#8216;View&#8217; class that we can use like osc_item_id(), osc_item_category_id(), etc<br \/>\nWe can use this code to get the &#8216;items&#8217; data by primary key without the helpers:<br \/>\n$item = Item::newInstance()-&gt;findByPrimaryKey($applicant[&#8216;fk_i_item_id&#8217;]);<br \/>\necho $item[&#8216;s_title&#8217;]; &#8211;&gt; CAN&#8217;T GET $item[&#8216;s_title&#8217;]<br \/>\nanother variations:<br \/>\nref:\/plugins\/mb_auction\/ModelMBAuction.php:<br \/>\nView::newInstance()-&gt;_exportVariableToView(&#8216;items&#8217;, Search::newInstance()-&gt;doSearch());<br \/>\nView::newInstance()-&gt;_exportVariableToView(&#8220;item&#8221;, Item::newInstance()-&gt;findByPrimaryKey($itemId));<br \/>\nref:\/plugins\/mb_auction\/themes\/default\/auction_dashboard_widget.php:<br \/>\nView::newInstance()-&gt;_exportVariableToView(&#8216;footer_link&#8217;, $f);<br \/>\n10. How to loop search result (can use osc_item_id())<br \/>\nPls do this:<br \/>\nref:\/osclass_plugin_test\/oc-content\/plugins\/plugin-jobboard-master\/people.php:<br \/>\n$mSearch = new Search();<br \/>\n$mSearch-&gt;limit(0, 100);<br \/>\n$aItems = $mSearch-&gt;doSearch();<br \/>\nView::newInstance()-&gt;_exportVariableToView(&#8216;items&#8217;, $aItems);<br \/>\nthen we can use the helpers functions like &#8216;osc_item_id()&#8217;<br \/>\nif we want to search something simple and just return the result count, we can do it like this:<br \/>\nref:\/osclass_plugin_test\/oc-content\/plugins\/plugin-jobboard-master\/dashboard.php:<br \/>\n&lt;?php<br \/>\n$mSearch = new Search(true);<br \/>\n$mSearch-&gt;addItemConditions(DB_TABLE_PREFIX.&#8217;t_item.b_enabled = 1&#8242;);<br \/>\n?&gt;<br \/>\n&lt;\/div&gt;<br \/>\n&lt;b&gt;&lt;?php echo $mSearch-&gt;count(); ?&gt;&lt;\/b&gt;<br \/>\n&#8216;new Search(true)&#8217; mean we can also search the &#8216;expired&#8217; item (ref:\/oc-includes\/osclass\/model\/Search.php)<br \/>\n&#8216;Search&#8217; class only to search data in the &#8216;oc_t_item&#8217; table.<br \/>\nor we can also use like this with some search queries (use &#8216;addItemConditions&#8217;):<br \/>\nref:\/kokopage\/oc-content\/themes\/classer\/functions.php: (similar query)<br \/>\nView::newInstance()-&gt;_exportVariableToView(&#8216;items&#8217;, array());\/\/I dont know if its better to empty the &#8216;items&#8217; first<br \/>\n$mSearch = new Search();<br \/>\n$mSearch-&gt;addCategory(osc_item_category_id());<br \/>\n$mSearch-&gt;addItemConditions(sprintf(&#8220;%st_item.pk_i_id != %s &#8220;, DB_TABLE_PREFIX, osc_item_id()));<br \/>\n$mSearch-&gt;limit(&#8216;0&#8217;, $max_item);<\/p>\n<p>$aItems = $mSearch-&gt;doSearch();<br \/>\n$iTotalItems = count($aItems);<br \/>\nif( $iTotalItems &gt; 0 ) {<br \/>\nView::newInstance()-&gt;_exportVariableToView(&#8216;items&#8217;, $aItems);<br \/>\nreturn $iTotalItems;<br \/>\n}<br \/>\nunset($mSearch);<\/p>\n<p>return 0;<br \/>\nthen in the loop:<br \/>\n&lt;?php while( osc_has_items() ) { ?&gt;<br \/>\n&lt;?php echo osc_item_id(); ?&gt;<br \/>\n&lt;?php } ?&gt;<\/p>\n<p>or we can also do like this (more complex queries):<br \/>\nref:\/osclass_plugin_test\/oc-content\/plugins\/plugin-jobboard-master\/dashboard.php:<br \/>\n$mSearch4 = new Search(true);<br \/>\n$mSearch4-&gt;addTable(DB_TABLE_PREFIX.&#8221;t_item_stats&#8221;);<br \/>\n$mSearch4-&gt;addField(&#8220;SUM(&#8220;.DB_TABLE_PREFIX.&#8221;t_item_stats.i_num_views) as i_num_views&#8221;);<br \/>\n$mSearch4-&gt;addConditions(DB_TABLE_PREFIX.&#8221;t_item_stats.fk_i_item_id = &#8220;.DB_TABLE_PREFIX.&#8221;t_item.pk_i_id&#8221;);<br \/>\n$mSearch4-&gt;order(&#8216;i_num_views&#8217;);<br \/>\n$mSearch4-&gt;set_rpp(1);<br \/>\n$mSearch4-&gt;addGroupBy(&#8220;fk_i_item_id&#8221;);<br \/>\n$mostViewedJob = $mSearch4-&gt;doSearch();<br \/>\nWithout export it to &#8216;View&#8217; because it only return 1 record, we can get the data without looping like this:<br \/>\n$mostViewedJob[0][&#8216;i_num_views&#8217;]<br \/>\n$mostViewedJob[0][&#8216;fk_i_item_id&#8217;]<br \/>\n$mostViewedJob[0][&#8216;s_title&#8217;]<\/p>\n<p>or even like this (more2 complex query):<br \/>\nref:\/kokopage\/oc-content\/themes\/classer\/functions.php: (featured listing):<br \/>\nfunction featured_listings() {<br \/>\n$category_id=0;<br \/>\n$category_query=&#8221;&#8221;;<br \/>\nif(Params::getParam(&#8216;sCategory&#8217;)){<br \/>\n$cats=array();<br \/>\n$cat=Category::newInstance()-&gt;findNameByPrimaryKey(Params::getParam(&#8216;sCategory&#8217;));<br \/>\nif($cat){<br \/>\n\/\/find in the sub category<br \/>\n$subCategories = Category::newInstance()-&gt;toSubTree(Params::getParam(&#8216;sCategory&#8217;));<br \/>\nif($subCategories){<br \/>\nforeach($subCategories as $s){<br \/>\n$cats[]=$s[&#8216;pk_i_id&#8217;];<br \/>\n}<br \/>\n$category_id=Params::getParam(&#8216;sCategory&#8217;).&#8217;,&#8217;.implode($cats,&#8217;,&#8217;);<br \/>\n$category_query=&#8221;IN (&#8220;.$category_id.&#8221;)&#8221;;<br \/>\n}else{<br \/>\n$category_id=Params::getParam(&#8216;sCategory&#8217;);<br \/>\n$category_query=&#8221;= &#8220;.$category_id;<br \/>\n}<br \/>\n}else{<br \/>\n\/\/category id is not exist<br \/>\n$category_id=-1;<br \/>\n$category_query=&#8221;= -1&#8243;;<br \/>\n}<br \/>\n}<br \/>\n$max_item=16;<br \/>\n$mSearch = new Search();<br \/>\n$mSearch-&gt;addTable(DB_TABLE_PREFIX.&#8221;t_item_promoted_ad&#8221;);<br \/>\n$mSearch-&gt;addConditions(DB_TABLE_PREFIX.&#8221;t_item.pk_i_id = &#8220;.DB_TABLE_PREFIX.&#8221;t_item_promoted_ad.fk_i_item_id&#8221;);<br \/>\nif($category_id)<br \/>\n$mSearch-&gt;addConditions(DB_TABLE_PREFIX.&#8221;t_item.fk_i_category_id &#8220;.$category_query);<br \/>\n$mSearch-&gt;addConditions(DB_TABLE_PREFIX.&#8221;t_item_promoted_ad.i_paid = 1&#8243;);<br \/>\n$mSearch-&gt;addConditions(DB_TABLE_PREFIX.&#8221;t_item_promoted_ad.dt_expiration IS NOT NULL&#8221;);<br \/>\n$mSearch-&gt;order(DB_TABLE_PREFIX.&#8221;t_item.pk_i_id&#8221;);<br \/>\n$mSearch-&gt;addGroupBy(DB_TABLE_PREFIX.&#8221;t_item.pk_i_id&#8221;);<br \/>\n$mSearch-&gt;limit(&#8216;0&#8217;, $max_item);<\/p>\n<p>$aItems = $mSearch-&gt;doSearch();<br \/>\n$iTotalItems = count($aItems);<br \/>\nif( $iTotalItems &gt; 0 ) {<br \/>\nView::newInstance()-&gt;_exportVariableToView(&#8216;items&#8217;, $aItems);<br \/>\nreturn $iTotalItems;<br \/>\n}<br \/>\nunset($mSearch);<\/p>\n<p>return 0;<br \/>\n}<\/p>\n<p>11. How to find &#8216;Total View&#8217;?<br \/>\npls use &#8216;ItemStats&#8217; static class like this:<br \/>\nref:\/osclass_plugin_test\/oc-content\/plugins\/plugin-jobboard-master\/dashboard.php:<br \/>\n&lt;?php echo ItemStats::newInstance()-&gt;getAllViews(); ?&gt;<\/p>\n<p>12. How to include another files outside our plugin?<br \/>\npls use like this: (to include core &#8216;oc-load.php&#8217;)<br \/>\nref:\/osclass_plugin_test\/oc-content\/plugins\/plugin-jobboard-master\/download.php:<br \/>\ndefine(&#8216;ABS_PATH&#8217;, dirname(dirname(dirname(dirname($_SERVER[&#8216;SCRIPT_FILENAME&#8217;])))) . &#8216;\/&#8217;);<br \/>\nrequire_once(ABS_PATH . &#8216;oc-load.php&#8217;);<br \/>\nor if we know the file we want to include in &#8216;\/oc-includes&#8217; directory, just use &#8216;osc_lib_path()&#8217; like this:<br \/>\nrequire_once(osc_lib_path() . &#8216;osclass\/helpers\/hErrors.php&#8217;);<br \/>\n13. How to make &#8216;download\/upload&#8217; pdf file?<br \/>\npls see in : \/osclass_plugin_test\/oc-content\/plugins\/plugin-jobboard-master\/download.php<br \/>\nalso use some &#8216;header&#8217; function like : header(&#8216;Content-Disposition: attachment; filename=&#8217; . $pdf_name);<br \/>\n13. How to upload file (ex: CV):<br \/>\npls see in : \/osclass_plugin_test\/oc-content\/plugins\/plugin-jobboard-master\/ReciveCv.php<br \/>\n13. How to resume Download?<br \/>\npls see in : \/osclass_plugin_test\/oc-content\/plugins\/plugin-jobboard-master\/resume_download.php<br \/>\n13. How to compress\/zip uploaded file with ZipArchive\/pclzip?<br \/>\npls see in : \/osclass_plugin_test\/oc-content\/plugins\/plugin-jobboard-master\/resumes_request.php<br \/>\n14. How to make email template?<br \/>\npls see in : \/osclass_plugin_test\/oc-content\/plugins\/plugin-jobboard-master\/email.php<br \/>\nthen send the email: osc_sendMail($params)<br \/>\n15. How to redirect via javascsript?<br \/>\npls use like this:<br \/>\nref:\/osclass_plugin_test\/oc-content\/plugins\/plugin-jobboard-master\/helpers.php:<br \/>\n&lt;?php<br \/>\nfunction job_js_redirect_to($url) { ?&gt;<br \/>\n&lt;script type=&#8221;text\/javascript&#8221;&gt;<br \/>\nwindow.location = &#8220;&lt;?php echo $url; ?&gt;&#8221;<br \/>\n&lt;\/script&gt;<br \/>\n&lt;?php }<br \/>\nand use like this:<br \/>\njob_js_redirect_to(osc_admin_render_plugin_url(&#8220;jobboard\/manage_killer.php&#8221;));<br \/>\n16. How to count\/measure elapsed time since the item (is published) until now?<br \/>\npls see: &#8216;_jobboard_time_elapsed_string&#8217; function in \/osclass_plugin_test\/oc-content\/plugins\/plugin-jobboard-master\/helpers.php<br \/>\n17. How to count\/measure the age\/birthday?<br \/>\npls see: &#8216;_jobboard_get_age&#8217; function in \/osclass_plugin_test\/oc-content\/plugins\/plugin-jobboard-master\/helpers.php<br \/>\n18. How to use ajax on the item form post\/edit?<br \/>\npls see: \/osclass_plugin_test\/oc-content\/plugins\/plugin-jobboard-master\/killer_form_frm.php<br \/>\nand &#8216;triggerKillerFormCreation&#8217; javascript function in \/osclass_plugin_test\/oc-content\/plugins\/plugin-jobboard-master\/assets\/js\/killerForm.js<br \/>\non action: pls create a new listing and select any category. pls play with &#8216;Killer Question&#8217; (http:\/\/localhost\/Projects\/osclass_plugin_test\/oc-admin\/index.php?page=items&amp;action=post)<br \/>\n19. How to get admin user data?<br \/>\npls use &#8216;Admin&#8217; static class like this:<br \/>\n$adminManager = Admin::newInstance();<br \/>\n$aAdmin\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 = $adminManager-&gt;findByPrimaryKey(osc_logged_admin_id());<br \/>\npls see: \/osclass_plugin_test\/oc-content\/plugins\/plugin-jobboard-master\/people_detail.php<br \/>\n20. How to find OSClass page?<br \/>\npls use &#8216;Page&#8217; static class like this:<br \/>\n$page = Page::newInstance()-&gt;findByInternalName(&#8217;email_resumes_jobboard&#8217;) ;<br \/>\n$page_description = $page[&#8216;locale&#8217;] ;<\/p>\n<p>$_title = osc_apply_filter(&#8217;email_title&#8217;, $page_description[$prefLocale][&#8216;s_title&#8217;]);<br \/>\n$_body\u00a0 = osc_apply_filter(&#8217;email_description&#8217;, $page_description[$prefLocale][&#8216;s_text&#8217;]);<br \/>\npls see: \/osclass_plugin_test\/oc-content\/plugins\/plugin-jobboard-master\/resumes_request.php<br \/>\n21. we can render custom &#8216;user menu&#8217; (the left section that hase some links like : dashboard, profile, account, paymnet, etc) on the user dashboard (like here http:\/\/localhost\/Projects\/kokopage\/index.php?page=user&amp;action=items). on the \/classer\/user-items.php we can display it like this:<br \/>\n&lt;div class=&#8221;userMenus boxwhite hasmb&#8221;&gt;<br \/>\n&lt;?php echo osc_private_user_menu( get_user_menu() ); ?&gt;<br \/>\n&lt;?php \/\/echo osc_private_user_menu(\u00a0 );\/\/&lt;&#8211;default user menu ?&gt;<br \/>\n&lt;\/div&gt;<br \/>\nHere is the custom &#8216;user menu&#8217; function &#8216;get_user_menu&#8217; defined in \/classer\/functions.php:<br \/>\nfunction get_user_menu() {<br \/>\n$options\u00a0\u00a0 = array();<br \/>\n$options[] = array(<br \/>\n&#8216;name&#8217; =&gt; __(&#8216;&lt;i class=&#8221;icon-certificate&#8221;&gt;&lt;\/i&gt; Public Profile&#8217;),<br \/>\n&#8216;url&#8217; =&gt; osc_user_public_profile_url(),<br \/>\n&#8216;class&#8217; =&gt; &#8216;opt_publicprofile&#8217;<br \/>\n);<br \/>\n$options[] = array(<br \/>\n&#8216;name&#8217;\u00a0 =&gt; __(&#8216;&lt;i class=&#8221;icon-list-numbered&#8221;&gt;&lt;\/i&gt; Listings&#8217;, &#8216;classer&#8217;),<br \/>\n&#8216;url&#8217;\u00a0\u00a0 =&gt; osc_user_list_items_url(),<br \/>\n&#8216;class&#8217; =&gt; &#8216;opt_items&#8217;<br \/>\n);<br \/>\n$options[] = array(<br \/>\n&#8216;name&#8217; =&gt; __(&#8216;&lt;i class=&#8221;icon-bell-alt&#8221;&gt;&lt;\/i&gt; Alerts&#8217;, &#8216;classer&#8217;),<br \/>\n&#8216;url&#8217; =&gt; osc_user_alerts_url(),<br \/>\n&#8216;class&#8217; =&gt; &#8216;opt_alerts&#8217;<br \/>\n);<br \/>\n$options[] = array(<br \/>\n&#8216;name&#8217;\u00a0 =&gt; __(&#8216;&lt;i class=&#8221;icon-cogs&#8221;&gt;&lt;\/i&gt; Account&#8217;, &#8216;classer&#8217;),<br \/>\n&#8216;url&#8217;\u00a0\u00a0 =&gt; osc_user_profile_url(),<br \/>\n&#8216;class&#8217; =&gt; &#8216;opt_account&#8217;<br \/>\n);<br \/>\n$options[] = array(<br \/>\n&#8216;name&#8217;\u00a0 =&gt; __(&#8216;&lt;i class=&#8221;icon-mail-2&#8243;&gt;&lt;\/i&gt; Change email&#8217;, &#8216;classer&#8217;),<br \/>\n&#8216;url&#8217;\u00a0\u00a0 =&gt; osc_change_user_email_url(),<br \/>\n&#8216;class&#8217; =&gt; &#8216;opt_change_email&#8217;<br \/>\n);<br \/>\n$options[] = array(<br \/>\n&#8216;name&#8217;\u00a0 =&gt; __(&#8216;&lt;i class=&#8221;icon-edit-1&#8243;&gt;&lt;\/i&gt; Edit username&#8217;, &#8216;classer&#8217;),<br \/>\n&#8216;url&#8217;\u00a0\u00a0 =&gt; osc_change_user_username_url(),<br \/>\n&#8216;class&#8217; =&gt; &#8216;opt_change_username&#8217;<br \/>\n);<br \/>\n$options[] = array(<br \/>\n&#8216;name&#8217;\u00a0 =&gt; __(&#8216;&lt;i class=&#8221;icon-key&#8221;&gt;&lt;\/i&gt; Change password&#8217;, &#8216;classer&#8217;),<br \/>\n&#8216;url&#8217;\u00a0\u00a0 =&gt; osc_change_user_password_url(),<br \/>\n&#8216;class&#8217; =&gt; &#8216;opt_change_password&#8217;<br \/>\n);<br \/>\n$options[] = array(<br \/>\n&#8216;name&#8217;\u00a0 =&gt; __(&#8216;&lt;i class=&#8221;icon-trash&#8221;&gt;&lt;\/i&gt; Delete account&#8217;, &#8216;classer&#8217;),<br \/>\n&#8216;url&#8217;\u00a0\u00a0 =&gt; &#8216;#&#8217;,<br \/>\n&#8216;class&#8217; =&gt; &#8216;opt_delete_account&#8217;<br \/>\n);<\/p>\n<p>return $options;<br \/>\n}<br \/>\n22. How to find out how many &#8216;paid ads&#8217; or &#8216;premium ads&#8217;?<br \/>\npls use this: (\/classer\/inc\/user-stats.php)<br \/>\n&lt;?php<br \/>\n$searchPrem = new Search();<br \/>\n$searchPrem-&gt;addConditions(sprintf(&#8220;b_premium = %d&#8221;, 1));<br \/>\n$searchPrem-&gt;addConditions(sprintf(&#8220;fk_i_user_id = %d&#8221;, osc_logged_user_id()));<br \/>\n$searchPrem-&gt;limit(0, 1000);\/\/&lt;&#8211; dont forget to add &#8216;limit&#8217;. somehow it just came up with 10 data<br \/>\n$premiumItems = $searchPrem-&gt;doSearch();<br \/>\necho count($premiumItems);<br \/>\n?&gt;<br \/>\nsomehow i can&#8217;t use &lt;?php echo osc_priv_count_premiums(); ?&gt;<br \/>\n23. How to find out how many &#8216;alerts&#8217;?<br \/>\npls use this: (\/classer\/inc\/user-stats.php)<br \/>\n&lt;?php<br \/>\n$searchAlert = new Search();<br \/>\n$searchAlert-&gt;addTable(DB_TABLE_PREFIX.&#8221;t_alerts&#8221;);<br \/>\n$searchAlert-&gt;addConditions(sprintf(&#8220;b_active = %d&#8221;, 1));<br \/>\n$searchAlert-&gt;addConditions(sprintf(&#8220;fk_i_user_id = %d&#8221;, osc_logged_user_id()));<br \/>\n$searchAlert-&gt;limit(0, 1000);\/\/&lt;&#8211; dont forget to add &#8216;limit&#8217;. somehow it just came up with 10 data<br \/>\n$alerts = $searchAlert-&gt;doSearch();<br \/>\necho count($alerts);<br \/>\n?&gt;<br \/>\nsomehow i can&#8217;t use &lt;?php echo osc_count_alerts(); ?&gt;<\/p>\n<p>24. jQuery is not be recognized in certain page (ie. user change email or user change password).<br \/>\nWe can include it at the top of those page by using:<br \/>\nosc_enqueue_script(&#8216;jquery-validate&#8217;);<br \/>\nnote: &#8216;jquery-validate&#8217; script must exist in the current theme.<br \/>\n25. &#8216;osc_user_items_validated&#8217; function in \/classer\/inc\/user-stats.php didnt work also on the overlay header. the case is same with above (&#8216;osc_user_id&#8217; didnt give any result so use &#8216;osc_logged_user_id&#8217; instead):<br \/>\n&lt;?php<br \/>\nif(osc_user_id())<br \/>\necho osc_user_items_validated();<br \/>\nelse{<br \/>\n$searchItem = new Search();<br \/>\n$searchItem-&gt;addConditions(sprintf(&#8220;b_enabled = %d&#8221;, 1));<br \/>\n$searchItem-&gt;addConditions(sprintf(&#8220;fk_i_user_id = %d&#8221;, osc_logged_user_id()));<br \/>\n$searchItem-&gt;limit(0, 1000);\/\/&lt;&#8211; dont forget to add &#8216;limit&#8217;. somehow it just came up with 10 data<br \/>\n$items = $searchItem-&gt;doSearch();<br \/>\necho count($items);<br \/>\n}<br \/>\n?&gt;<br \/>\n26. Modifying the pagination display:<br \/>\nref: \/plugins\/payment\/admin\/manage.php:<br \/>\nfunction showingResults(){<br \/>\n$aData = __get(&#8220;aData&#8221;);<br \/>\necho &#8216;&lt;ul class=&#8221;showing-results&#8221;&gt;&lt;li&gt;&lt;span&gt;&#8217;.osc_pagination_showing((Params::getParam(&#8216;iPage&#8217;)-1)*$aData[&#8216;iDisplayLength&#8217;]+1, ((Params::getParam(&#8216;iPage&#8217;)-1)*$aData[&#8216;iDisplayLength&#8217;])+count($aData[&#8216;aRows&#8217;]), $aData[&#8216;iTotalDisplayRecords&#8217;], $aData[&#8216;iTotalRecords&#8217;]).'&lt;\/span&gt;&lt;\/li&gt;&lt;\/ul&gt;&#8217;;<br \/>\n}<br \/>\nosc_add_hook(&#8216;before_show_pagination_admin&#8217;,&#8217;showingResults&#8217;);<br \/>\nosc_show_pagination_admin($aData);<\/p>\n<p>27. Load the items with the pagination:<br \/>\nref:kokopage\/oc-content\/plugins\/watchlist\/watchlist.php<br \/>\n$i_userId = osc_logged_user_id();<br \/>\nif(Params::getParam(&#8216;delete&#8217;) != &#8221; &amp;&amp; osc_is_web_user_logged_in()){<br \/>\ndelete_item(Params::getParam(&#8216;delete&#8217;), $i_userId);<br \/>\n}<\/p>\n<p>$itemsPerPage = (Params::getParam(&#8216;itemsPerPage&#8217;) != &#8221;) ? Params::getParam(&#8216;itemsPerPage&#8217;) : 5;<br \/>\n$iPage\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 = (Params::getParam(&#8216;iPage&#8217;) != &#8221;) ? Params::getParam(&#8216;iPage&#8217;) : 0;<\/p>\n<p>Search::newInstance()-&gt;addConditions(sprintf(&#8220;%st_item_watchlist.fk_i_user_id = %d&#8221;, DB_TABLE_PREFIX, $i_userId));<br \/>\nSearch::newInstance()-&gt;addConditions(sprintf(&#8220;%st_item_watchlist.fk_i_item_id = %st_item.pk_i_id&#8221;, DB_TABLE_PREFIX, DB_TABLE_PREFIX));<br \/>\nSearch::newInstance()-&gt;addTable(sprintf(&#8220;%st_item_watchlist&#8221;, DB_TABLE_PREFIX));<br \/>\nSearch::newInstance()-&gt;page($iPage, $itemsPerPage);<\/p>\n<p>$aItems\u00a0\u00a0\u00a0\u00a0\u00a0 = Search::newInstance()-&gt;doSearch();<br \/>\n$iTotalItems = Search::newInstance()-&gt;count();<br \/>\n$iNumPages\u00a0\u00a0 = ceil($iTotalItems \/ $itemsPerPage) ;<\/p>\n<p>View::newInstance()-&gt;_exportVariableToView(&#8216;items&#8217;, $aItems);<br \/>\nView::newInstance()-&gt;_exportVariableToView(&#8216;search_total_pages&#8217;, $iNumPages);<br \/>\nView::newInstance()-&gt;_exportVariableToView(&#8216;search_page&#8217;, $iPage) ;<\/p>\n<p>or kokopage\/oc-content\/plugins\/payment\/user\/menu.php<br \/>\n&lt;?php<br \/>\n$itemsPerPage = (Params::getParam(&#8216;itemsPerPage&#8217;) != &#8221;) ? Params::getParam(&#8216;itemsPerPage&#8217;) : 4;<br \/>\n$page\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 = (Params::getParam(&#8216;iPage&#8217;) != &#8221;) ? Params::getParam(&#8216;iPage&#8217;) : 0;<br \/>\n$total_items\u00a0 = Item::newInstance()-&gt;countByUserID(osc_logged_user_id());<br \/>\n$total_pages\u00a0 = ceil($total_items\/$itemsPerPage);<br \/>\n$items\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 = Item::newInstance()-&gt;findByUserID(osc_logged_user_id(), $page * $itemsPerPage, $itemsPerPage);<\/p>\n<p>View::newInstance()-&gt;_exportVariableToView(&#8216;items&#8217;, $items);<br \/>\nView::newInstance()-&gt;_exportVariableToView(&#8216;list_total_pages&#8217;, $total_pages);<br \/>\nView::newInstance()-&gt;_exportVariableToView(&#8216;list_total_items&#8217;, $total_items);<br \/>\nView::newInstance()-&gt;_exportVariableToView(&#8216;items_per_page&#8217;, $itemsPerPage);<br \/>\nView::newInstance()-&gt;_exportVariableToView(&#8216;list_page&#8217;, $page);<br \/>\n?&gt;<br \/>\nor \/plugins\/mb_auction\/themes\/default\/auction_dashboard_widget.php:<br \/>\n$itemsPerPage = (Params::getParam(&#8216;itemsPerPage&#8217;)!=&#8221;)?Params::getParam(&#8216;itemsPerPage&#8217;):10;<br \/>\n$page\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 = (Params::getParam(&#8216;iPage&#8217;) &gt; 0) ? Params::getParam(&#8216;iPage&#8217;) -1 : 0;<\/p>\n<p>Search::newInstance()-&gt;addTable(sprintf(&#8220;%st_item_auction&#8221;, DB_TABLE_PREFIX));<br \/>\nSearch::newInstance()-&gt;addConditions(sprintf(&#8220;%st_item.pk_i_id = %st_item_auction.fk_i_item_id &#8220;, DB_TABLE_PREFIX, DB_TABLE_PREFIX));<br \/>\nSearch::newInstance()-&gt;addConditions(sprintf(&#8220;%st_item.fk_i_user_id = &#8220;.osc_logged_user_id(), DB_TABLE_PREFIX));<br \/>\nSearch::newInstance()-&gt;order(sprintf(&#8220;%st_item.pk_i_id&#8221;, DB_TABLE_PREFIX),&#8217;DESC&#8217;,&#8221;);<br \/>\nSearch::newInstance()-&gt;page($page, $itemsPerPage);<br \/>\n$aItems\u00a0\u00a0\u00a0\u00a0\u00a0 = Search::newInstance()-&gt;doSearch();<br \/>\n$iTotalItems = Search::newInstance()-&gt;count();<br \/>\n$iNumPages\u00a0\u00a0 = ceil($iTotalItems \/ $itemsPerPage) ;<br \/>\nView::newInstance()-&gt;_exportVariableToView(&#8216;items&#8217;, $aItems);<br \/>\nView::newInstance()-&gt;_exportVariableToView(&#8216;search_total_pages&#8217;, $iNumPages);<br \/>\nView::newInstance()-&gt;_exportVariableToView(&#8216;search_page&#8217;, $page) ;<\/p>\n<p>29. If we manually loop some items and we want to show the items properties (like title, description, images, etc), usually we can do it by using like this:<br \/>\n&lt;?php foreach($payments as $pay) { ?&gt;<br \/>\n&#8230;<br \/>\n&lt;?php<br \/>\n$itemId=$pay[&#8216;fk_i_item_id&#8217;];<br \/>\nif($itemId != 0){<br \/>\nView::newInstance()-&gt;_exportVariableToView(&#8220;item&#8221;, Item::newInstance()-&gt;findByPrimaryKey($itemId));<br \/>\n&#8230;<br \/>\n?&gt;<br \/>\n&lt;?php if(osc_count_item_resources()) { ?&gt;<br \/>\n&lt;div class=&#8221;img&#8221;&gt;<br \/>\n&lt;a class=&#8221;listing-thumb&#8221; href=&#8221;&lt;?php echo osc_item_url() ; ?&gt;&#8221; title=&#8221;&lt;?php echo osc_esc_html(osc_item_title()) ; ?&gt;&#8221;&gt;<br \/>\n&lt;img src=&#8221;&lt;?php echo osc_resource_thumbnail_url(); ?&gt;&#8221; title=&#8221;&#8221; alt=&#8221;&lt;?php echo osc_esc_html(osc_item_title()) ; ?&gt;&#8221; width=&#8221;&lt;?php echo $size[0]; ?&gt;&#8221; height=&#8221;&lt;?php echo $size[1]; ?&gt;&#8221;&gt;<br \/>\n&lt;\/a&gt;<br \/>\n&lt;\/div&gt;<br \/>\n&lt;?php } else { ?&gt;<br \/>\n&lt;div class=&#8221;img&#8221;&gt;<br \/>\n&lt;a class=&#8221;listing-thumb&#8221; href=&#8221;&lt;?php echo osc_item_url() ; ?&gt;&#8221; title=&#8221;&lt;?php echo osc_esc_html(osc_item_title()) ; ?&gt;&#8221;&gt;<br \/>\n&lt;img src=&#8221;&lt;?php echo osc_current_web_theme_url(&#8216;images\/no_photo.gif&#8217;); ?&gt;&#8221; title=&#8221;&#8221; alt=&#8221;&lt;?php echo osc_esc_html(osc_item_title()) ; ?&gt;&#8221; width=&#8221;&lt;?php echo $size[0]; ?&gt;&#8221; height=&#8221;&lt;?php echo $size[1]; ?&gt;&#8221;&gt;<br \/>\n&lt;\/a&gt;<br \/>\n&lt;\/div&gt;<br \/>\n&lt;?php } ?&gt;<br \/>\n&lt;?php<br \/>\n&#8230;<br \/>\n}<br \/>\n?&gt;<br \/>\n&lt;?php } ?&gt;<br \/>\nBUT IF WE DID LIKE ABOVE WE&#8217;D FIND THE SAME IMAGE FOR EACH ITEM. THIS IS HAPPENED BECAUSE WE FORGET TO CLEAR THE &#8216;resources&#8217; KEY FROM THE PREVIOUS ITEM!!!. SO DO LIKE THIS:<br \/>\n&lt;?php foreach($payments as $pay) { ?&gt;<br \/>\n&lt;?php<br \/>\nif(View::newInstance()-&gt;_exists(&#8216;item&#8217;))<br \/>\nView::newInstance()-&gt;_erase(&#8216;item&#8217;);<br \/>\nif(View::newInstance()-&gt;_exists(&#8216;resources&#8217;))<br \/>\nView::newInstance()-&gt;_erase(&#8216;resources&#8217;);<br \/>\n$itemId=$pay[&#8216;fk_i_item_id&#8217;];<br \/>\nif($itemId != 0){<br \/>\nView::newInstance()-&gt;_exportVariableToView(&#8220;item&#8221;, Item::newInstance()-&gt;findByPrimaryKey($itemId));<br \/>\n&#8230;<br \/>\n?&gt;<br \/>\nView::newInstance()-&gt;_erase(&#8216;resources&#8217;) WILL CLEAR THE PREVIOUS &#8216;resources&#8217; KEY, SO &#8216;osc_count_item_resources&#8217; function WOULD LOAD THE NEW ONE. PLS SEE &#8216;osc_count_item_resources&#8217; function code in \/oc-includes\/osclass\/helpers\/hItems.php<br \/>\nref:\/plugins\/payment\/user\/user-payment-list.php<br \/>\nlink:http:\/\/localhost\/Projects\/kokopage\/index.php?page=custom&amp;route=user-payment-list-url<\/p>\n<p>30. When we use &#8216;osc_redirect_to&#8217; function, sometime we get some warning:<br \/>\n&#8216;Warning: Cannot modify header information &#8211; headers already sent by&#8230;&#8217;<br \/>\nthen we use &#8216;header&#8217; instead. I THINK WE STILL CAN USE &#8216;osc_redirect_to&#8217; function by adding &#8216;ob_get_clean()&#8217; function on the previous line like this: (TODO: NEED TEST!!!)<br \/>\n&#8230;<br \/>\n\/\/ HACK : This will make possible use of the flash messages \ud83d\ude09<br \/>\nob_get_clean();<br \/>\nosc_add_flash_ok_message(__(&#8216;Congratulations, the plugin is now configured&#8217;, &#8216;cookie&#8217;), &#8216;admin&#8217;);<br \/>\nosc_redirect_to(osc_route_admin_url(&#8216;cookie-conf&#8217;));<br \/>\nref:\/plugins\/cookies\/admin\/conf.php<\/p>\n<p>31. IS A CUSTOM HOOK BEHAVIOUR LIKE GLOBAL FUNCTIONS????? IT CAN BE CALLED FROM ANYWHERE???<\/p>\n<p>32. Customized get latest Items<br \/>\nView::newInstance()-&gt;_exportVariableToView(&#8216;items&#8217;, $osclassItems);<br \/>\nif(osc_is_home_page()) {<br \/>\n$latestSearch = new Search();<br \/>\n$latestSearch-&gt;limit (0, osc_get_preference(&#8216;maxLatestItems@home&#8217;, &#8216;osclass&#8217;));<br \/>\n$latestItems = $latestSearch-&gt;getLatestItems();<\/p>\n<p>View::newInstance()-&gt;_exportVariableToView(&#8216;items&#8217;, $latestItems);<br \/>\n}<br \/>\nref:\/osclass_plugin_test\/oc-content\/plugins\/carousel_for_osclass\/carousel_detail.php<\/p>\n<p>33. How to validate form input on the plugins (for plugin admin page also)<br \/>\nRegister and enqueue &#8216;jquery-validate&#8217; on the init hook like this:<br \/>\nref:\/osclass.3.5.9\/oc-content\/plugins\/mb_auction\/index.php<br \/>\nfunction mb_auction_load_js_css() {<br \/>\n&#8230;<br \/>\nosc_register_script(&#8216;auction_js&#8217;, mb_auction_plugin_directory().&#8217;js\/auction.js&#8217;, &#8216;jquery&#8217;);<br \/>\nosc_register_script(&#8216;jquery-validate&#8217;, osc_base_url() . &#8216;oc-includes\/osclass\/assets\/js\/jquery.validate.min.js&#8217;, &#8216;jquery&#8217;);<br \/>\nosc_register_script(&#8216;jquery-validate-additional&#8217;, mb_auction_plugin_directory().&#8217;js\/additional-methods.min.js&#8217;, array(&#8216;jquery&#8217;, &#8216;jquery-validate&#8217;,&#8217;jquery-ui&#8217;));<\/p>\n<p>&#8230;<br \/>\nosc_enqueue_script(&#8216;auction_js&#8217;);<br \/>\nosc_enqueue_script(&#8216;jquery-validate&#8217;);<br \/>\nosc_enqueue_script(&#8216;jquery-validate-additional&#8217;);<\/p>\n<p>osc_enqueue_style(&#8216;auctionCss&#8217;, mb_auction_plugin_directory().&#8217;css\/style.css&#8217;);<br \/>\n}<br \/>\nthen you can use it anywhere on your plugin:<br \/>\nref:\/osclass.3.5.9\/oc-content\/plugins\/mb_auction\/admin\/manage.php<br \/>\n&lt;script type=&#8221;text\/javascript&#8221;&gt;<br \/>\n$(document).ready(function() {<br \/>\n$.validator.addMethod(&#8216;min_lower_max&#8217;,function(value,element){<br \/>\nreturn value &lt;= parseInt($(&#8220;#max_auction_length&#8221;).val());<br \/>\n},'&lt;?php echo osc_esc_js(__(&#8220;Minimum Auction Length (Days) should be lower than Maximum Auction Length (Days)&#8221;, &#8220;mb_auction&#8221;)); ?&gt;.&#8217;);<br \/>\n$.validator.addMethod(&#8216;max_greater_min&#8217;,function(value,element){<br \/>\nreturn value &gt;= parseInt($(&#8220;#min_auction_length&#8221;).val());<br \/>\n},'&lt;?php echo osc_esc_js(__(&#8220;Maximum Auction Length (Days) should be greater than Minimum Auction Length (Days)&#8221;, &#8220;mb_auction&#8221;)); ?&gt;.&#8217;);<\/p>\n<p>$(&#8216;form#mb_auction_form&#8217;).validate({<br \/>\nrules: {<br \/>\nmin_auction_length: {<br \/>\nrequired: true,<br \/>\nnumber: true,<br \/>\nmin: 1,<br \/>\nmin_lower_max: true<br \/>\n},<br \/>\nmax_auction_length: {<br \/>\nrequired: true,<br \/>\nnumber: true,<br \/>\nmin: 1,<br \/>\nmax_greater_min: true<br \/>\n},<br \/>\nmin_auction_increment_price: {<br \/>\nrequired: true,<br \/>\nnumber: true,<br \/>\nmin: 0<br \/>\n}<br \/>\n},<br \/>\nmessages: {<br \/>\nmin_auction_length: {<br \/>\nrequired: &#8216;&lt;?php echo osc_esc_js(__(&#8220;Minimum Auction Length (Days)&#8221;, &#8220;mb_auction&#8221;)); ?&gt;: &lt;?php echo osc_esc_js(__(&#8220;this field is required&#8221;, &#8220;mb_auction&#8221;)); ?&gt;.&#8217;,<br \/>\nnumber: &#8216;&lt;?php echo osc_esc_js(__(&#8220;Minimum Auction Length (Days)&#8221;, &#8220;mb_auction&#8221;)); ?&gt;: &lt;?php echo osc_esc_js(__(&#8220;enter valid number&#8221;, &#8220;mb_auction&#8221;)); ?&gt;.&#8217;,<br \/>\nmin: &#8216;&lt;?php echo osc_esc_js(__(&#8220;Minimum Auction Length (Days)&#8221;, &#8220;mb_auction&#8221;)); ?&gt;: &lt;?php echo osc_esc_js(__(&#8220;Minimum length is &#8220;, &#8220;mb_auction&#8221;)); ?&gt;1.&#8217;<br \/>\n},<br \/>\nmax_auction_length: {<br \/>\nrequired: &#8216;&lt;?php echo osc_esc_js(__(&#8220;Maximum Auction Length (Days)&#8221;, &#8220;mb_auction&#8221;)); ?&gt;: &lt;?php echo osc_esc_js(__(&#8220;this field is required&#8221;, &#8220;mb_auction&#8221;)); ?&gt;.&#8217;,<br \/>\nnumber: &#8216;&lt;?php echo osc_esc_js(__(&#8220;Maximum Auction Length (Days)&#8221;, &#8220;mb_auction&#8221;)); ?&gt;: &lt;?php echo osc_esc_js(__(&#8220;enter valid number&#8221;, &#8220;mb_auction&#8221;)); ?&gt;.&#8217;,<br \/>\nmin: &#8216;&lt;?php echo osc_esc_js(__(&#8220;Maximum Auction Length (Days)&#8221;, &#8220;mb_auction&#8221;)); ?&gt;: &lt;?php echo osc_esc_js(__(&#8220;Minimum length is &#8220;, &#8220;mb_auction&#8221;)); ?&gt;1.&#8217;<br \/>\n},<br \/>\nmin_auction_increment_price: {<br \/>\nrequired: &#8216;&lt;?php echo osc_esc_js(__(&#8220;Minimum Auction Increment Price&#8221;, &#8220;mb_auction&#8221;)); ?&gt;: &lt;?php echo osc_esc_js(__(&#8220;this field is required&#8221;, &#8220;mb_auction&#8221;)); ?&gt;.&#8217;,<br \/>\nnumber: &#8216;&lt;?php echo osc_esc_js(__(&#8220;Minimum Auction Increment Price&#8221;, &#8220;mb_auction&#8221;)); ?&gt;: &lt;?php echo osc_esc_js(__(&#8220;enter valid price&#8221;, &#8220;mb_auction&#8221;)); ?&gt;.&#8217;,<br \/>\nmin: &#8216;&lt;?php echo osc_esc_js(__(&#8220;Minimum Auction Increment Price&#8221;, &#8220;mb_auction&#8221;)); ?&gt;: &lt;?php echo osc_esc_js(__(&#8220;Minimum price is &#8220;, &#8220;mb_auction&#8221;)); ?&gt;0.&#8217;<br \/>\n}<br \/>\n},<br \/>\nerrorLabelContainer: &#8220;#error_list&#8221;,<br \/>\nwrapper: &#8220;li&#8221;,<br \/>\ninvalidHandler: function(form, validator) {<br \/>\n$(&#8216;html,body&#8217;).animate({ scrollTop: $(&#8216;h1&#8217;).offset().top }, { duration: 250, easing: &#8216;swing&#8217;});<br \/>\n},<br \/>\nsubmitHandler: function(form){<br \/>\n$(&#8216;button[type=submit], input[type=submit]&#8217;).attr(&#8216;disabled&#8217;, &#8216;disabled&#8217;);<br \/>\nform.submit();<br \/>\n}<br \/>\n});<br \/>\n});<br \/>\n&lt;\/script&gt;<\/p>\n<p>34. more complex jquery validate implementation:<br \/>\nref:motobroker\/oc-content\/themes\/tuffclassified\/user-register.php<br \/>\n&lt;script&gt;<br \/>\n$( document ).ready(function() {<br \/>\n$(&#8220;#s_email2&#8221;).attr(&#8220;autocomplete&#8221;,&#8221;off&#8221;);<br \/>\n$(&#8220;form[name=register]&#8221;).validate({<br \/>\nrules: {<br \/>\ns_fname: {<br \/>\nrequired: true,<br \/>\nminlength: 2<br \/>\n},<br \/>\ns_lname: {<br \/>\nrequired: true,<br \/>\nminlength: 2<br \/>\n},<br \/>\ns_email: {<br \/>\nrequired: true,<br \/>\nemail: true<br \/>\n},<br \/>\ns_email2: {<br \/>\nrequired: true,<br \/>\nemail: true,<br \/>\nequalTo: &#8220;#s_email&#8221;<br \/>\n},<br \/>\ns_password: {<br \/>\nrequired: true,<br \/>\nminlength: 5<br \/>\n},<br \/>\ns_password2: {<br \/>\nrequired: true,<br \/>\nminlength: 5,<br \/>\nequalTo: &#8220;#s_password&#8221;<br \/>\n}<br \/>\n&lt;?php<br \/>\nif(in_array(&#8220;mb_memberships\/index.php&#8221;,$plugins_list)){<br \/>\n?&gt;<br \/>\n,<br \/>\nagree: {<br \/>\nrequired: {<br \/>\ndepends: function(element) {<br \/>\nreturn $(&#8220;#seller_type&#8221;).val()==&#8221;DEALER&#8221;;<br \/>\n}<br \/>\n}<br \/>\n},<br \/>\ndealer_name: {<br \/>\nrequired: {<br \/>\ndepends: function(element) {<br \/>\nreturn $(&#8220;#agree&#8221;).is(&#8220;:checked&#8221;);<br \/>\n}<br \/>\n},<br \/>\nminlength: 3<br \/>\n},<br \/>\ndealer_country: {<br \/>\nrequired: true<br \/>\n},<br \/>\ndealer_region: {<br \/>\nrequired: true<br \/>\n},<br \/>\ndealer_city: {<br \/>\nrequired: true<br \/>\n},<br \/>\ndealer_address: {<br \/>\nrequired: {<br \/>\ndepends: function(element) {<br \/>\nreturn $(&#8220;#agree&#8221;).is(&#8220;:checked&#8221;);<br \/>\n}<br \/>\n},<br \/>\nminlength: 5<br \/>\n},<br \/>\ndealer_phone: {<br \/>\nrequired: {<br \/>\ndepends: function(element) {<br \/>\nreturn $(&#8220;#agree&#8221;).is(&#8220;:checked&#8221;);<br \/>\n}<br \/>\n},<br \/>\nminlength: 5<br \/>\n},<br \/>\ndealer_license: {<br \/>\nrequired: {<br \/>\ndepends: function(element) {<br \/>\nreturn $(&#8220;#agree&#8221;).is(&#8220;:checked&#8221;);<br \/>\n}<br \/>\n},<br \/>\nminlength: 5<br \/>\n},<br \/>\ndealer_logo: {<br \/>\nrequired: {<br \/>\ndepends: function(element) {<br \/>\nreturn $(&#8220;#agree&#8221;).is(&#8220;:checked&#8221;) &amp;&amp; $(&#8220;#dealer_logo&#8221;).val() != &#8220;&#8221;;<br \/>\n}<br \/>\n},<br \/>\naccept: &#8220;image\/*&#8221;,<br \/>\nextension: &#8220;png|jpg|gif&#8221;<br \/>\n},<br \/>\ndealer_logo_size: {<br \/>\nrequired: {<br \/>\ndepends: function(element) {<br \/>\nreturn $(&#8220;#agree&#8221;).is(&#8220;:checked&#8221;) &amp;&amp; $(&#8220;#dealer_logo&#8221;).val() != &#8220;&#8221;;<br \/>\n}<br \/>\n},<br \/>\nmax: 105000<br \/>\n},<br \/>\ndealer_about: {<br \/>\nrequired: {<br \/>\ndepends: function(element) {<br \/>\nreturn $(&#8220;#agree&#8221;).is(&#8220;:checked&#8221;);<br \/>\n}<br \/>\n},<br \/>\nminlength: 5<br \/>\n},<br \/>\n&lt;?php<br \/>\n}<br \/>\n?&gt;<br \/>\n},<br \/>\nmessages: {<br \/>\ns_fname: {<br \/>\nrequired: &#8220;&lt;?php _e(&#8220;First Name: this field is required&#8221;); ?&gt;.&#8221;,<br \/>\nminlength: &#8220;&lt;?php _e(&#8220;Enter at least 2 characters&#8221;); ?&gt;.&#8221;<br \/>\n},<br \/>\ns_lname: {<br \/>\nrequired: &#8220;&lt;?php _e(&#8220;Last Name: this field is required&#8221;); ?&gt;.&#8221;,<br \/>\nminlength: &#8220;&lt;?php _e(&#8220;Enter at least 2 characters&#8221;); ?&gt;.&#8221;<br \/>\n},<br \/>\ns_email: {<br \/>\nrequired: &#8220;&lt;?php _e(&#8220;Email: this field is required&#8221;); ?&gt;.&#8221;,<br \/>\nemail: &#8220;&lt;?php _e(&#8220;Invalid email address&#8221;); ?&gt;.&#8221;<br \/>\n},<br \/>\ns_email2: {<br \/>\nrequired: &#8220;&lt;?php _e(&#8220;Email: this field is required&#8221;); ?&gt;.&#8221;,<br \/>\nemail: &#8220;&lt;?php _e(&#8220;Invalid email address&#8221;); ?&gt;.&#8221;,<br \/>\nequalTo: &#8220;&lt;?php _e(&#8220;Email don&#8217;t match&#8221;); ?&gt;.&#8221;<br \/>\n},<br \/>\ns_password: {<br \/>\nrequired: &#8220;&lt;?php _e(&#8220;Password: this field is required&#8221;); ?&gt;.&#8221;,<br \/>\nminlength: &#8220;&lt;?php _e(&#8220;Password: enter at least 5 characters&#8221;); ?&gt;.&#8221;<br \/>\n},<br \/>\ns_password2: {<br \/>\nrequired: &#8220;&lt;?php _e(&#8220;Second password: this field is required&#8221;); ?&gt;.&#8221;,<br \/>\nminlength: &#8220;&lt;?php _e(&#8220;Second password: enter at least 5 characters&#8221;); ?&gt;.&#8221;,<br \/>\nequalTo: &#8220;&lt;?php _e(&#8220;Passwords don&#8217;t match&#8221;); ?&gt;.&#8221;<br \/>\n}<br \/>\n&lt;?php<br \/>\nif(in_array(&#8220;mb_memberships\/index.php&#8221;,$plugins_list)){<br \/>\n?&gt;<br \/>\n,<br \/>\nagree: {<br \/>\nrequired: &#8220;&lt;?php _e(&#8220;Please check &#8216;Agree&#8217; for user dealer&#8221;); ?&gt;.&#8221;<br \/>\n},<br \/>\ndealer_country: {<br \/>\nrequired: &#8220;&lt;?php _e(&#8220;Country: this field is required&#8221;); ?&gt;.&#8221;<br \/>\n},<br \/>\ndealer_region: {<br \/>\nrequired: &#8220;&lt;?php _e(&#8220;Region\/State: this field is required&#8221;); ?&gt;.&#8221;<br \/>\n},<br \/>\ndealer_city: {<br \/>\nrequired: &#8220;&lt;?php _e(&#8220;City\/Suburb: this field is required&#8221;); ?&gt;.&#8221;<br \/>\n},<br \/>\ndealer_name: {<br \/>\nrequired: &#8220;&lt;?php _e(&#8220;Name: this field is required&#8221;); ?&gt;.&#8221;,<br \/>\nminlength: &#8220;&lt;?php _e(&#8220;Enter at least 3 characters&#8221;); ?&gt;.&#8221;<br \/>\n},<br \/>\ndealer_address: {<br \/>\nrequired: &#8220;&lt;?php _e(&#8220;Address: this field is required&#8221;); ?&gt;.&#8221;,<br \/>\nminlength: &#8220;&lt;?php _e(&#8220;Enter at least 3 characters&#8221;); ?&gt;.&#8221;<br \/>\n},<br \/>\ndealer_phone: {<br \/>\nrequired: &#8220;&lt;?php _e(&#8220;Phone Number: this field is required&#8221;); ?&gt;.&#8221;,<br \/>\nminlength: &#8220;&lt;?php _e(&#8220;Enter at least 3 characters&#8221;); ?&gt;.&#8221;<br \/>\n},<br \/>\ndealer_license: {<br \/>\nrequired: &#8220;&lt;?php _e(&#8220;License Number: this field is required&#8221;); ?&gt;.&#8221;,<br \/>\nminlength: &#8220;&lt;?php _e(&#8220;Enter at least 3 characters&#8221;); ?&gt;.&#8221;<br \/>\n},<br \/>\ndealer_logo: {<br \/>\naccept: &#8220;&lt;?php _e(&#8220;Accept only image file (jpg, png or gif)&#8221;); ?&gt;.&#8221;,<br \/>\nextension: &#8220;&lt;?php _e(&#8220;Accept only image file with these extensions (jpg, png or gif)&#8221;); ?&gt;.&#8221;<br \/>\n},<br \/>\ndealer_logo_size: {<br \/>\nmax: &#8220;&lt;?php _e(&#8220;Maximum image size is 100kb&#8221;); ?&gt;.&#8221;<br \/>\n},<br \/>\ndealer_about: {<br \/>\nrequired: &#8220;&lt;?php _e(&#8220;About Us: this field is required&#8221;); ?&gt;.&#8221;,<br \/>\nminlength: &#8220;&lt;?php _e(&#8220;Enter at least 3 characters&#8221;); ?&gt;.&#8221;<br \/>\n}<br \/>\n&lt;?php<br \/>\n}<br \/>\n?&gt;<br \/>\n},<br \/>\nhighlight: function(element) {<br \/>\n$(element).closest(&#8216;.form-group&#8217;).addClass(&#8216;has-warning&#8217;);<br \/>\n},<br \/>\nunhighlight: function(element) {<br \/>\n$(element).closest(&#8216;.form-group&#8217;).removeClass(&#8216;has-warning&#8217;);<br \/>\n},<br \/>\nerrorElement: &#8216;span&#8217;,<br \/>\nerrorClass: &#8216;help-block&#8217;,<br \/>\nerrorPlacement: function(error, element) {<br \/>\nif(element.parent(&#8216;.input-group&#8217;).length) {<br \/>\nerror.insertAfter(element.parent());<br \/>\n} else {<br \/>\nerror.insertAfter(element);<br \/>\n}<br \/>\nif($(&#8220;span[for=&#8217;s_fname&#8217;]&#8221;).length &amp;&amp; $(&#8220;span[for=&#8217;s_lname&#8217;]&#8221;).length){<br \/>\n$(&#8220;span[for=&#8217;s_fname&#8217;]&#8221;).prependTo(&#8220;span[for=&#8217;s_lname&#8217;]&#8221;);<br \/>\n}<br \/>\n},<br \/>\nsuccess: function() {<br \/>\nvar fname=$(&#8220;#s_fname&#8221;).val().trim();<br \/>\nvar lname=$(&#8220;#s_lname&#8221;).val().trim();<br \/>\n$(&#8220;#s_name&#8221;).val(fname+&#8221; &#8220;+lname);<br \/>\n}<br \/>\n});<\/p>\n<p>});<\/p>\n<p>&lt;\/script&gt;<\/p>\n<p>OSCLASS FUNCTIONS:<br \/>\n1. osc_highlight<br \/>\nnote: to display some portion of text<br \/>\nuse: osc_highlight(@$item[&#8216;s_title&#8217;],30) \/\/just display 30 char<br \/>\n2. osc_admin_render_plugin_url<br \/>\nnote: to display the current plugin url on admin page (usually it is used in &lt;a&gt; tag)<br \/>\nuse: &lt;a href=&#8221;&#8216;.osc_admin_render_plugin_url(&#8220;jobboard\/people.php&#8221;).&#8217;&amp;iStatus=&#8217;.$k.'&#8221;&gt;&#8217;.__(&#8216;View all&#8217;,&#8217;jobboard&#8217;).&#8217; &#8216;.$v.'&lt;\/a&gt;<br \/>\nor<br \/>\njob_js_redirect_to(osc_admin_render_plugin_url(&#8220;jobboard\/manage_killer.php&#8221;));<br \/>\nto display the current plugin url on front page, pls use &#8216;osc_plugin_folder&#8217; like this:<br \/>\n&lt;a href=&#8221;#&#8221; class=&#8221;star&#8221; star=&#8221;&#8216;.$k.'&#8221; id=&#8221;rating_&#8217;.$applicantId.&#8217;_&#8217;.$k.'&#8221; &gt;&lt;img src=&#8221;&#8216;.osc_base_url().&#8217;oc-content\/plugins\/&#8217;.osc_plugin_folder(__FILE__).&#8217;img\/&#8217;.($k&lt;=$rating?&#8217;fullstar.png&#8217;:&#8217;emptystar.png&#8217;).'&#8221;\/&gt;&lt;\/a&gt;<br \/>\n3. osc_admin_base_url<br \/>\nnote: to display base admin page url (with &#8216;true&#8217; would display also index.php)<br \/>\nuse: &lt;a href=&#8221;&lt;?php echo osc_admin_base_url(true); ?&gt;?page=items&#8221; style=&#8221;text-decoration:none;&#8221;&gt;<br \/>\n4. osc_is_admin_user_logged_in<br \/>\nnote: only logged in admin can use\/enter\/access<br \/>\nuse: if(!osc_is_admin_user_logged_in()) {<br \/>\ndie;<br \/>\n}<br \/>\n5. osc_die<br \/>\nnote: is it same with &#8216;die()&#8217; ??? but we can write something at the end;<br \/>\nuse: osc_die($title, $message);<br \/>\nref:\/osclass_plugin_test\/oc-content\/plugins\/plugin-jobboard-master\/download.php:<br \/>\n6. osc_sanitizeString<br \/>\nnote: remove empty string\/space in a text??<br \/>\nuse:$filename\u00a0 = osc_sanitizeString($applicant[&#8216;s_name&#8217;]);<br \/>\nref:\/osclass_plugin_test\/oc-content\/plugins\/plugin-jobboard-master\/download.php:<br \/>\n7. osc_max_images_per_item<br \/>\nnote: display how many image can be uploaded for an item<br \/>\nuse: if( osc_max_images_per_item() &gt; 0 ) {<br \/>\nosc_set_preference(&#8216;numImages@items&#8217;, 0);<br \/>\n}<br \/>\nref:\/osclass_plugin_test\/oc-content\/plugins\/plugin-jobboard-master\/helpers.php:<br \/>\n8. osc_item_attachment<br \/>\nnote : display\/check if this item has any attachment<br \/>\nuse: if( !osc_item_attachment() ) {<br \/>\nosc_set_preference(&#8216;item_attachment&#8217;, true);<br \/>\n}<br \/>\nref:\/osclass_plugin_test\/oc-content\/plugins\/plugin-jobboard-master\/helpers.php:<br \/>\n9. osc_price_enabled_at_items<br \/>\nnote : check if this item can be put any price<br \/>\nuse: if( osc_price_enabled_at_items() ) {<br \/>\nosc_set_preference(&#8216;enableField#f_price@items&#8217;, false);<br \/>\n}<br \/>\nref:\/osclass_plugin_test\/oc-content\/plugins\/plugin-jobboard-master\/helpers.php:<br \/>\n10. osc_images_enabled_at_items<br \/>\nnote : check if this item can be uploaded any image<br \/>\nuse: if( osc_images_enabled_at_items() ) {<br \/>\nosc_set_preference(&#8216;enableField#images@items&#8217;, false);<br \/>\n}<br \/>\nref:\/osclass_plugin_test\/oc-content\/plugins\/plugin-jobboard-master\/helpers.php:<br \/>\n11. osc_plugin_path<br \/>\nnote: to display url for the current plugin (may be better for &#8216;hook&#8217; and &#8216;register&#8217; plugin)<br \/>\nuse:<br \/>\nosc_register_plugin(osc_plugin_path(__FILE__), array( new JobboardInstallUpdate(), &#8216;job_call_after_install&#8217;) );<br \/>\nosc_add_hook(osc_plugin_path(__FILE__).&#8221;_uninstall&#8221;, array( new JobboardInstallUpdate(), &#8216;job_call_after_uninstall&#8217;) );<br \/>\nref:\/osclass_plugin_test\/oc-content\/plugins\/plugin-jobboard-master\/index.php:<br \/>\nfor &#8216;register&#8217; script (js\/css), pls use &#8216;osc_plugin_url&#8217; like this:<br \/>\nosc_register_script(&#8216;jquery-rating&#8217;, osc_plugin_url(__FILE__) . &#8216;assets\/lib\/rating\/jquery.rating.js&#8217;, &#8216;jquery&#8217;);<br \/>\nref:\/osclass_plugin_test\/oc-content\/plugins\/plugin-jobboard-master\/index.php:<br \/>\n12. osc_current_user_locale<br \/>\nnote: find the locale language<br \/>\nuse:\u00a0\u00a0\u00a0 $locale\u00a0\u00a0\u00a0 = osc_current_user_locale();<br \/>\n$detail[&#8216;locale&#8217;][$locale][&#8216;s_studies&#8217;]<br \/>\nref:\/osclass_plugin_test\/oc-content\/plugins\/plugin-jobboard-master\/item_detail.php:<br \/>\n13. osc_get_locales<br \/>\nnote: find all language installed<br \/>\nuse:\u00a0\u00a0\u00a0 foreach(osc_get_locales() as $locale) {<br \/>\necho $locale[&#8216;pk_c_code&#8217;];<br \/>\n}<br \/>\nref:\/osclass_plugin_test\/oc-content\/plugins\/plugin-jobboard-master\/item_edit.php:<br \/>\n13. osc_language<br \/>\nnote: find the current language??<br \/>\nuse:<br \/>\n$prefLocale = osc_language() ;<br \/>\n$_title = osc_apply_filter(&#8217;email_title&#8217;, $page_description[$prefLocale][&#8216;s_title&#8217;]);<br \/>\nref:\/osclass_plugin_test\/oc-content\/plugins\/plugin-jobboard-master\/resumes_request.php:<br \/>\n14. osc_esc_html<br \/>\nnote: display a text with html tag ??<br \/>\nuse: echo osc_esc_html(__(&#8216;Delete question&#8217;, &#8216;jobboard&#8217;));<br \/>\n15. osc_doRequest<br \/>\nnote:???<br \/>\nuse: pls see in \/osclass_plugin_test\/oc-content\/plugins\/plugin-jobboard-master\/resume_download.php<br \/>\nif(Params::getParam(&#8216;paction&#8217;)==&#8217;createpack&#8217;) {<br \/>\n$params = array(<br \/>\n&#8216;page&#8217; =&gt; &#8216;ajax&#8217;<br \/>\n,&#8217;action&#8217; =&gt; &#8216;custom&#8217;<br \/>\n,&#8217;ajaxfile&#8217; =&gt; osc_plugin_folder(__FILE__).&#8221;resumes_request.php&#8221;<br \/>\n);<br \/>\nosc_doRequest(osc_base_url(), $params);<br \/>\n}<br \/>\n16. osc_add_filter and osc_apply_filter<br \/>\nref: \/oc-includes\/osclass\/helpers\/hPlugins.php<br \/>\nref: \/oc-includes\/osclass\/classes\/Plugins.php (applyFilter)<br \/>\nnote: to modify the osclass filter content with the user defined function\/text???<br \/>\nuse:<br \/>\nfunction applicant_admin_menu_current($class) {<br \/>\nif( urldecode(Params::getParam(&#8216;file&#8217;)) === &#8216;jobboard\/people_detail.php&#8217; ) {<br \/>\nreturn &#8216;current&#8217;;<br \/>\n}<br \/>\nreturn $class;<br \/>\n}<br \/>\nosc_add_filter(&#8216;current_admin_menu_corporateboard&#8217;, &#8216;applicant_admin_menu_current&#8217;);\/\/predefined function<br \/>\nuse:<br \/>\n$_title = osc_apply_filter(&#8217;email_title&#8217;, $page_description[$prefLocale][&#8216;s_title&#8217;]);\/\/predefined text<br \/>\nref: \/osclass_plugin_test\/oc-content\/plugins\/plugin-jobboard-master\/resumes_request.php<br \/>\nif we want to set a hook content as empty??? with no predefined function\/callback and text, we can do like this:<br \/>\nosc_add_filter(&#8216;bender_bodyClass&#8217;,&#8217;bender_add_body_class_construct&#8217;);<br \/>\n$classes = osc_apply_filter(&#8216;bender_bodyClass&#8217;, array());<br \/>\nref: \/osclass_plugin_test\/oc-content\/themes\/bender\/functions.php<br \/>\nlearn (also for osc_add_hook and osc_run_hook):<br \/>\nfunc_get_args() \/\/Returns an array comprising a function&#8217;s argument list. pls see:http:\/\/php.net\/manual\/en\/function.func-get-args.php<br \/>\nand<br \/>\ncall_user_func_array()\u00a0 \/\/Call a callback with an array of parameters. pls see:http:\/\/php.net\/manual\/en\/function.call-user-func-array.php<br \/>\n17. osc_logged_admin_name and osc_logged_admin_id<br \/>\nnote: find admin username and id respectively<br \/>\nuse:<br \/>\necho osc_logged_admin_name()<br \/>\necho osc_logged_admin_id()<br \/>\nwhen send email from admin, we can do like this:<br \/>\n$words[] = array(<br \/>\nosc_logged_admin_name()<br \/>\n,$list<br \/>\n);<br \/>\nref: \/osclass_plugin_test\/oc-content\/plugins\/plugin-jobboard-master\/resumes_request.php<br \/>\n18. osc_mailBeauty<br \/>\nnote: beautify\/tidify email content???<br \/>\nuse:<br \/>\n$title = osc_mailBeauty($_title, $words);<br \/>\n$body\u00a0 = osc_mailBeauty($_body , $words);<br \/>\nref: \/osclass_plugin_test\/oc-content\/plugins\/plugin-jobboard-master\/resumes_request.php<\/p>\n<p>19. Params::getParamsAsArray()<\/p>\n<p>20. osc_is_web_user_logged_in(), osc_logged_user_id()<\/p>\n<p>21. osc_esc_js<br \/>\nnote: display translation for javascript\/jquery<br \/>\nuse: $(&#8220;#available&#8221;).text(&#8216;&lt;?php echo osc_esc_js(__(&#8220;The username is available&#8221;, &#8220;bender&#8221;)); ?&gt;&#8217;);<br \/>\nref: \/themes\/bender\/user-change_username.php<\/p>\n<p>OSCLASS PROBLEMS &amp; SOLUTIONS :<br \/>\n1. Problem : homepage\/admin show blank page<br \/>\nSolution : Put define(&#8216;OSC_DEBUG&#8217;, true) ; in config.php and refresh browser. pls see the error\/warning output<br \/>\nor chmod 777 -R the osclass directory<br \/>\nor check again config.php (at part REL_WEB_URL and WEB_PATH)<\/p>\n<p>2. Problem : front page show &#8220;We are sorry for any inconvenience. MyPage is undergoing maintenance.&#8221;<br \/>\nSolution : go to admin page (\/oc-admin) on the browser then Show more -&gt; Tools -&gt; Maintenance mode then click &#8220;Disable maintenance mode&#8221;<br \/>\nthen refresh again the front page<\/p>\n<p>3. Problem : Warning : cannot open &#8216;HTMLPurifier\/Bootstrap.php&#8217;. failed to open in &#8230;..<br \/>\nSolution : May be you just renamed the directory of the osclass project and the osclass cache still intact. pls change back the directory name and refresh<\/p>\n<p>4. Problem : The requested URL \/index.php was not found on this server.(can&#8217;t open url-friendly page)<br \/>\nSolution : check again your .htaccess<br \/>\nif the root of osclass in a sub directory, so change from<br \/>\n&lt;IfModule mod_rewrite.c&gt;<br \/>\nRewriteEngine On<br \/>\nRewriteBase \/<br \/>\nRewriteRule ^index\\.php$ &#8211; [L]<br \/>\nRewriteCond %{REQUEST_FILENAME} !-f<br \/>\nRewriteCond %{REQUEST_FILENAME} !-d<br \/>\nRewriteRule . \/index.php [L]<br \/>\nOptions -MultiViews<br \/>\n&lt;\/IfModule&gt;<br \/>\nto (for example)<br \/>\n&lt;IfModule mod_rewrite.c&gt;<br \/>\nRewriteEngine On<br \/>\nRewriteBase \/Projects\/motobroker\/<br \/>\nRewriteRule ^index\\.php$ &#8211; [L]<br \/>\nRewriteCond %{REQUEST_FILENAME} !-f<br \/>\nRewriteCond %{REQUEST_FILENAME} !-d<br \/>\nRewriteRule . \/Projects\/motobroker\/index.php [L]<br \/>\n&lt;\/IfModule&gt;<\/p>\n<p>5. Problem : Can&#8217;t open the plugin link. for example this link : http:\/\/motobroker.dev\/oc-admin\/index.php?page=plugins&amp;action=renderplugin&amp;route=mb-facebook-manage&amp;section=facebook just open a blank content<br \/>\nSolution : Check another plugin for the same route name. for example in mb_auction, there is &#8216;mb-facebook-manage&#8217; route. after searching in another plugin, there is a same route in get_my_listing plugin. Pls change\/rename the route in one of the plugin.<\/p>\n<p>6. Add\/attach &#8216;image&#8217; (also how many image can be attached) and\/or add &#8216;Price&#8217; was not displayed on the item post\/edit page<br \/>\nSolution: There is a setting in admin page -&gt; Listings -&gt; Settings (or by url:http:\/\/localhost\/Projects\/osclass_plugin_test\/oc-admin\/index.php?page=items&amp;action=settings)<br \/>\nPls check on &#8216;Optional fields&#8217; : &#8216;Attach Images&#8217; and &#8216;Price&#8217;<br \/>\nTo set how many image can be attached, pls fill the &#8216;Attach ### images per listing&#8217;<\/p>\n<p>LEARN THIS!!<br \/>\nHOW &#8216;wallet_button&#8217; function defined in \/plugins\/payment\/functions.php CAN BE CALLED FROM \/plugins\/promote_ad\/user\/payment.php???<br \/>\nTHE SAME CASE FOR &#8216;Paypal::button&#8217; static function defined in \/plugins\/payment\/payments\/paypal\/Paypal.php ??<br \/>\nTHE SAME CASE FOR &#8216;StripePayment::button&#8217; static function defined in \/plugins\/payment\/payments\/stripe\/StripePayment.php ???<br \/>\nSOLUTION!!!<br \/>\nIn \/plugins\/payment\/index.php, THOSE FUNCTIONS ALREADY INCLUDED GLOBALLY! LIKE THIS:<\/p>\n<pre class=\"lang:default decode:true \">...\r\ndefine('PAYMENT_CRYPT_KEY', 'anewrandompass12');\r\n\/\/ PAYMENT STATUS\r\ndefine('PAYMENT_FAILED', 0);\r\ndefine('PAYMENT_COMPLETED', 1);\r\ndefine('PAYMENT_PENDING', 2);\r\ndefine('PAYMENT_ALREADY_PAID', 3);\r\n\r\n\/\/ load necessary functions\r\nrequire_once osc_plugins_path() . osc_plugin_folder(__FILE__) . 'functions.php';    \/\/for calling wallet_button\r\nrequire_once osc_plugins_path() . osc_plugin_folder(__FILE__) . 'ModelPayment.php';\r\n\/\/ Load different methods of payments\r\nif(osc_get_preference('paypal_enabled', 'payment')==1) {\r\n    require_once osc_plugins_path() . osc_plugin_folder(__FILE__) . 'payments\/paypal\/Paypal.php'; \/\/for calling Paypal::button\r\n}\r\n...\r\nif(osc_get_preference('stripe_enabled', 'payment')==1) {\r\n    require_once osc_plugins_path() . osc_plugin_folder(__FILE__) . 'payments\/stripe\/StripePayment.php'; \/\/for calling StripePayment::button\r\n    osc_add_hook('ajax_stripe', array('StripePayment', 'ajaxPayment'));\r\n}\r\n...<\/pre>\n<p>SO WHEN THE payment PLUGIN IS LOADED, ANOTHER PLUGIN CAN CALL THE FUNCTION???<br \/>\nWHAT IS THE DIFFERENT WITH osc_add_hook(&#8216;init&#8217;, &#8216;payment_load_lib&#8217;);???<br \/>\nOR osc_add_hook(osc_plugin_path(__FILE__).&#8221;_enable&#8221;, &#8216;payment_update_version&#8217;);???<\/p>\n<p>SETUP OSCLASS 3.7.4 WITH NGINX AND PHP7.0-FPM ON UBUNTU 16.04<br \/>\nref: https:\/\/www.mindstellar.com\/osclass-nginx-php-fpm-better-performance<\/p>\n<ul>\n<li>Create the config file\n<pre class=\"lang:default decode:true\">sudo gedit \/etc\/nginx\/sites-available\/osclass374.test<\/pre>\n<p>Here is the content:<\/p>\n<pre class=\"lang:default decode:true\">server {\r\n    listen 80; \r\n    listen [::]:80;\r\n    root \/home\/teddy\/Documents\/works\/osclass374; #your document root\r\n    server_name www.osclass374.test osclass374.test ;  # Your server name\r\n    index index.php index.html index.htm ;\r\n\r\n    # Webfonts,fonts\r\n    location ~* \\.(?:ttf|ttc|otf|eot|woff|woff2)$ {\r\n        add_header \"Access-Control-Allow-Origin\" \"*\";\r\n        expires 1y;\r\n        access_log off;\r\n        add_header Cache-Control \"public\";\r\n    }\r\n\r\n    # Media: images, icons, video, audio, HTC\r\n    location ~* \\.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {\r\n        expires 1y;\r\n        access_log off;\r\n        add_header Cache-Control \"public\";\r\n    }\r\n\r\n    # Js, Css\r\n    location ~* \\.(?:css|js)$ {\r\n        expires 1y;\r\n        access_log off;\r\n        add_header Cache-Control \"public\";\r\n    }\r\n\r\n    # Serve static files without touching php\r\n    location \/ {\r\n        try_files $uri $uri\/ \/index.php?$args;\r\n    } \r\n    # pass requests for dynamic content to site\r\n    location ~ [^\/]\\.php(\/|$) {\r\n        try_files $uri \/index.php; \r\n        fastcgi_pass unix:\/run\/php\/php7.0-fpm.sock;\r\n        \r\n        fastcgi_buffers 1024 4k;\r\n\r\n        fastcgi_read_timeout 600s;\r\n        fastcgi_connect_timeout 600s;\r\n\r\n        fastcgi_index index.php;\r\n        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;\r\n        #include fastcgi_params;\r\n        #FOR DEVELOPMENT MODE ONLY - BEGIN\r\n        fastcgi_param MAGE_IS_DEVELOPER_MODE true;\r\n        fastcgi_param PHP_VALUE  display_startup_errors=on;\r\n        fastcgi_param PHP_VALUE  display_errors=on;\r\n        fastcgi_param PHP_VALUE  html_errors=on;\r\n        fastcgi_param PHP_VALUE  log_errors=on;\r\n        fastcgi_param PHP_VALUE  error_log=\/home\/teddy\/Documents\/works\/osclass374\/var\/log\/system.log;\r\n        #FOR DEVELOPMENT MODE ONLY - END\r\n        include fastcgi_params;\r\n    }\r\n\r\n    gzip on;\r\n    gzip_disable \"msie6\";\r\n\r\n    gzip_comp_level 6;\r\n    gzip_min_length 1100;\r\n    gzip_buffers 16 8k;\r\n    gzip_proxied any;\r\n    gzip_types\r\n    text\/plain\r\n    text\/css\r\n    text\/js\r\n    text\/xml\r\n    text\/javascript\r\n    application\/javascript\r\n    application\/x-javascript\r\n    application\/json\r\n    application\/xml\r\n    application\/xml+rss\r\n    image\/svg+xml;\r\n    gzip_vary on;\r\n\r\n    # Banned locations (only reached if the earlier PHP entry point regexes don't match)\r\n    location ~* (\\.php$|\\.htaccess$|\\.git) {\r\n        deny all;\r\n    }\r\n}<\/pre>\n<\/li>\n<li>Enable file config\n<pre class=\"lang:default decode:true\">sudo ln -s \/etc\/nginx\/sites-available\/osclass374.test \/etc\/nginx\/sites-enabled\/osclass374.test<\/pre>\n<\/li>\n<li>Register the host on my system\n<pre class=\"lang:default decode:true\">sudo gedit \/etc\/hosts<\/pre>\n<p>Like this:<\/p>\n<pre class=\"lang:default decode:true\">...\r\n127.0.0.1 \tosclass374.test\r\n...<\/pre>\n<\/li>\n<li>CHECK THE NGINX SETTING AND RESTART IT:\n<pre class=\"lang:default decode:true\">teddy@teddy:~$ sudo nginx -t\r\nnginx: the configuration file \/etc\/nginx\/nginx.conf syntax is ok\r\nnginx: configuration file \/etc\/nginx\/nginx.conf test is successful<\/pre>\n<pre class=\"lang:default decode:true\">sudo systemctl restart nginx<\/pre>\n<p>&nbsp;<\/li>\n<li>Set file permission and owner:\n<pre class=\"lang:default decode:true\">teddy@teddy:~\/Documents\/works$ sudo chown www-data:www-data -R osclass374\/<\/pre>\n<p>&nbsp;<\/p>\n<p>Test: http:\/\/osclass374.test\/ &#8211;&gt; WORKING<br \/>\nhttp:\/\/osclass374.test\/oc-admin &#8211;&gt; user: admin; pass: admin<\/li>\n<li>USE API<br \/>\nref: https:\/\/github.com\/jun283\/aRestAPI4Osclass<br \/>\nDownload the code (zip) then extract in osclass root directory. It&#8217;d be better to rename the extracted dir to &#8216;api&#8217;. So it&#8217;d be \/osclass374\/api\/v0.1\/&#8230;Then modify nginx config to enable the API endpoint calling<\/p>\n<pre class=\"lang:default decode:true \">sudo gedit \/etc\/nginx\/sites-available\/osclass374.test<\/pre>\n<p>Modify like this (add location \/api\/v0.1\/):<br \/>\nref: https:\/\/stackoverflow.com\/questions\/29087426\/how-to-configure-rewrite-rules-for-small-api-using-nginx<\/p>\n<pre class=\"lang:default decode:true\">...\r\n# Serve static files without touching php\r\nlocation \/ {\r\n    try_files $uri $uri\/ \/index.php?$args;\r\n} \r\n\r\n# Handle api\/v0.1 sub project\r\nlocation \/api\/v0.1\/ {\r\n    # Debug output\r\n    #return 200 $args; add_header Content-Type text\/plain;\r\n\r\n    # Root for this sub project\r\n    #root \/var\/www\/api-v1\/public;\r\n\r\n    # Rewrite $uri=\/api\/v1\/xyz back to just $uri=\/xyz\r\n    rewrite ^\/api\/v0.1\/(.*)\/?$ \/api\/v0.1\/index.php?uri=$1 last;\r\n\r\n    # Try to send static file at $url or $uri\/\r\n    # Else try \/index.php (which will hit location ~\\.php$ below)\r\n    #try_files $uri $uri\/ \/index.php?$args;\r\n}\r\n\r\n# pass requests for dynamic content to site\r\nlocation ~ [^\/]\\.php(\/|$) {\r\n...\r\n}<\/pre>\n<p>Save then Restart nginx<br \/>\nTest like this: (SEARCH THE LIST OF END POINT IN \/home\/teddy\/Documents\/works\/osclass374\/api\/v0.1\/apiServer.php FILE)<br \/>\nhttp:\/\/osclass374.test\/api\/v0.1\/category\/<br \/>\nit&#8217;d give output(json):<\/p>\n<pre class=\"lang:default decode:true \">[\r\n  {\r\n    \"pk_i_id\": \"1\",\r\n    \"fk_i_parent_id\": null,\r\n    \"i_expiration_days\": \"0\",\r\n    \"i_position\": \"1\",\r\n    \"b_enabled\": \"1\",\r\n    \"b_price_enabled\": \"1\",\r\n    \"s_icon\": null,\r\n    \"fk_i_category_id\": \"1\",\r\n    \"fk_c_locale_code\": \"en_US\",\r\n    \"s_name\": \"For sale\",\r\n    \"s_description\": null,\r\n    \"s_slug\": \"for-sale\",\r\n    \"i_num_items\": \"1\"\r\n  },\r\n  {\r\n    \"pk_i_id\": \"2\",\r\n    ...\r\n...\r\n  },\r\n  {\r\n    \"pk_i_id\": \"95\",\r\n    \"fk_i_parent_id\": \"8\",\r\n    \"i_expiration_days\": \"0\",\r\n    \"i_position\": \"21\",\r\n    \"b_enabled\": \"1\",\r\n    \"b_price_enabled\": \"1\",\r\n    \"s_icon\": null,\r\n    \"fk_i_category_id\": \"95\",\r\n    \"fk_c_locale_code\": \"en_US\",\r\n    \"s_name\": \"Other Jobs\",\r\n    \"s_description\": null,\r\n    \"s_slug\": \"other-jobs\",\r\n    \"i_num_items\": \"0\"\r\n  }\r\n]<\/pre>\n<p>http:\/\/osclass374.test\/api\/v0.1\/category\/9<br \/>\nit&#8217;d give output (json):<\/p>\n<pre class=\"lang:default decode:true \">[\r\n  {\r\n    \"pk_i_id\": \"9\",\r\n    \"fk_i_parent_id\": \"1\",\r\n    \"i_expiration_days\": \"0\",\r\n    \"i_position\": \"1\",\r\n    \"b_enabled\": \"1\",\r\n    \"b_price_enabled\": \"1\",\r\n    \"s_icon\": null,\r\n    \"fk_i_category_id\": \"9\",\r\n    \"fk_c_locale_code\": \"en_US\",\r\n    \"s_name\": \"Animals\",\r\n    \"s_description\": null,\r\n    \"s_slug\": \"animals\",\r\n    \"i_num_items\": \"1\"\r\n  }\r\n]<\/pre>\n<p>&nbsp;<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Create a plugin to remove ad\/listing spam. currently the item list only can show 100 ad max. create a plugin so it can remove as many ad as we want???<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[36],"tags":[],"class_list":["post-565","post","type-post","status-publish","format-standard","hentry","category-osclass"],"_links":{"self":[{"href":"https:\/\/myprojects.advchaweb.com\/index.php\/wp-json\/wp\/v2\/posts\/565","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/myprojects.advchaweb.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/myprojects.advchaweb.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/myprojects.advchaweb.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/myprojects.advchaweb.com\/index.php\/wp-json\/wp\/v2\/comments?post=565"}],"version-history":[{"count":20,"href":"https:\/\/myprojects.advchaweb.com\/index.php\/wp-json\/wp\/v2\/posts\/565\/revisions"}],"predecessor-version":[{"id":7388,"href":"https:\/\/myprojects.advchaweb.com\/index.php\/wp-json\/wp\/v2\/posts\/565\/revisions\/7388"}],"wp:attachment":[{"href":"https:\/\/myprojects.advchaweb.com\/index.php\/wp-json\/wp\/v2\/media?parent=565"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/myprojects.advchaweb.com\/index.php\/wp-json\/wp\/v2\/categories?post=565"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/myprojects.advchaweb.com\/index.php\/wp-json\/wp\/v2\/tags?post=565"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}