PHPStorm autocomplete for CakePHP custom helpers in view files - cakephp

I use PhpStorm 6.0.2 and CakePHP 2.3.
In my controller file I define this and get autocomplete for my custom components:
/**
* #property MysuperComponent $Mysuper
*/
Regarding to this, in my view files I define this to reach Cake's core helpers and this works:
/**
* #var $this View
*/
I need autocomplete for custom helpers inside my views. I tried this but didn't work:
/**
* #property Myelegant $MyelegantHelper
*/
When I do this, this works partially:
/**
* #var $Myelegant MyelegantHelper
*/
I get this $Myelegant-> autocomplete. But it isn't adequate. I need autocomplete like this: $this->Myelegant->
Notes: Autocomplete successfully works for core helpers inside view (ctp) files. But not for custom helpers.

Add new file /app/View/HintView.php
Add your custom helpers' names on PHPDoc.
<?php
App::uses('View', 'View');
/**
* #property MyelegantHelper $Myelegant
* */
class HintView extends View {
}
Inside your layout files or View files (ctp files) add this code on top
/**
* #var $this HintView
*/
Now inside your views you can see like this:
$this->MyElegant
->Blocks
->Cache
->Form
$this->MyElegant->somefunction()
anotherfunction()
oldfunction()
You don't have to extend your Views from HintView. It is only for PhpStorm's autocomplete.
(Note that you can make it faster with creating shortcuts to codes. For example goto Settins / IDE Settings / Live Templates. Add new template. For example "myeleg" for "$this->MyElegant->" So when you write "myeleg" and press Tab key it will write the class name automatically)

Have you tried looking at this article:
http://blog.hwarf.com/2011/08/configure-phpstorm-to-auto-complete.html
Look at the section "Setting Up Helper Auto-completion in Views". Hopefully this helps.

I know this is an old post, but came across this having the same issue. Solved it this way:
For me, my custom helper is called StatusHelper, so needed the #property as follows:
App::uses('Helper', 'View');
/**
* #property StatusHelper $Status
* */
class StatusHelper extends AppHelper {
Then in the view .ctp file, I just needed the following at the top:
<?php /* #var $this View|StatusHelper */ ?>
Now the autocomplete works for my PHPstorm in that view for both core View vars as well as whatever ever methods are in my helper.. Happy days
Using Cake 2.5 - PHPstorm 10. Hope this helps someone else out there...

Is Easy, Test in CakePHP 3.x to PHPStrom, supports namespace.
Add in to file views.ctp type PHPDoc
<?php /** #var $this Cake\View\View */ ?>

Related

How to enable Auto Complete in PHPStorm for CakePHP templates

How to enable Auto Complete in PHPStorm for CakePHP templates.
For example $this and its functions, Helpers ... etc in the *.ctp files
Just add a type hint comment on top of your view code:
<?php
/* #var $this \App\View\AppView */
For the records, in pre-namespaced CakePHP/2.x it used to be:
<?php
/* #var $this View */

Cakephp Plugin to generate sitemap

I'm using Cakephp 2.4.3 . I've read that "There are CakePHP plugins that are able to generate sitemaps for you. This way your sitemap.xml file will be created dynamically on demand and will always be up to date." . I've searched but all I find are from old cakephp version which is not useful as they only cause errors .
Is there still a good plugin for this?
Some plugins definitely exist:
https://github.com/sdevore/cakephp-sitemap-plugin
https://github.com/smarek/Croogo-Sitemap-2.0
https://github.com/webtechnick/CakePHP-Seo-Plugin
Are these the old, error-causing ones? As each CakePHP site can be radically different to the next, I'm not sure a one-size-fits-all solution will exist.
If you end up writing your own sitemap implementation, it'll depend mainly on whether your site has:
Lots of database-driven content with few controllers/actions (like a typical WordPress-style site)
Lots of controller/action driven content (more of a web application)
In the first case, you'd want to perform finds on your content, and inject the results into an xml template like this: http://bakery.cakephp.org/articles/masterkeedu/2008/08/26/automatically-generate-dynamic-sitemaps
For the second case, the following may help: a component I've used for development/testing, which lists all controllers and their methods:
<?php //File: app/Controller/Component/CtrlComponent.php
// Component rewritten for Cake2.x, original from : http://cakebaker.42dh.com/2006/07/21/how-to-list-all-controllers/
class CtrlComponent extends Component {
/**
* Return an array of Controllers and their methods.
* The function will exclude ApplicationController methods
* #return array
*/
public function get() {
$aCtrlClasses = App::objects('controller');
foreach ($aCtrlClasses as $controller) {
if ($controller != 'AppController') {
// Load the controller
App::import('Controller', str_replace('Controller', '', $controller));
// Load its methods / actions
$aMethods = get_class_methods($controller);
foreach ($aMethods as $idx => $method) {
if ($method{0} == '_') {
unset($aMethods[$idx]);
}
}
// Load the ApplicationController (if there is one)
App::import('Controller', 'AppController');
$parentActions = get_class_methods('AppController');
$controllers[$controller] = array_diff($aMethods, $parentActions);
}
}
return $controllers;
}
}
In reality, a full sitemap probably uses both methods, and you'll need to consider the difference between public and "private" areas of your site (excluding admin prefixes, for example)..

JSDoc with AngularJS

Currently within my Project we are using JSDoc, we have recently started to implement Angular and I want to continue using JSDoc to ensure that all the documentation is within the same place.
I have taken a look at people mainly just saying to use ngDoc but this isn't really a viable option as we will always have separate JavaScript and I ideally would have everything together.
/**
* #author Example <jon.doe#example.com>
* #copyright 2014 Example Ltd. All rights reserved.
*/
(function () {
window.example = window.example || {};
/**
* Example Namespace
* #memberOf example
* #namespace example.angular
*/
window.example.angular = window.example.angular || {};
var exAngular = window.example.angular;
/**
* A Example Angular Bootstrap Module
* #module exampleAngularBootstrap
*/
exAngular.bootstrap = angular.module('exampleAngularBootstrap', [
'ngRoute',
'ngResource',
'ngCookies'
])
.run(function ($http, $cookies) {
$http.defaults.headers.post['X-CSRFToken'] = $cookies.csrftoken;
$http.defaults.headers.common['X-CSRFToken'] = $cookies.csrftoken;
});
})();
Currently this is what I have but am unable to put documentation for the run() any ideas?
I have encountered this issue as well. I am now writing documentation for angularjs codes through jsdoc comments like this:
1.Make a blank .js file with the following comment:
/**
* #namespace angular_module
*/
This will create a separate html in the generated documentation for listing all modules.
2.In javascript files that defines any new angular module, use this kind of comment
/**
* #class angular_module.MyModule
* #memberOf angular_module
*/
This will add an item in the above listing of all angular_modules, as well as creating a separate html page for MyModule, because it is a class.
3.For each angularjs service, use the following comment:
/**
* #function myService
* #memberOf angular_module.MyModule
* #description This is an angularjs service.
*/
This will add an item in the MyModule page for the service. Because it is added as a function, you can write documentation for input parameters using '#param' and return values using '#return'.
4.If I have quite long codes in a controller or directive of MyModule and want to have a separate html file to document it, I will annotate the controller or directive as a class using full path. e.g.
/**
* #class angular_module.MyModule.MyController
*/
In this way, MyController will be listed as one item in MyModule's documentation page.
Then, we can annotate codes within the controller as member functions of MyController.
/**
* #name $scope.aScopeFunction
* #function
* #memberOf angular_module.MyModule.MyController
* #description
*/
In this way, this function's documentation will appear in the html file of MyController's html page. The dot-separated full path string builds the connection.
There are three types of syntaxes for namepath:
Person#say // the instance method named "say."
Person.say // the static method named "say."
Person~say // the inner method named "say."
However, one imperfect point of commenting controller as a class is that a "new" will be found before the controller name in the generated html documentation because it is described as class constructor.
Furthermore, you can define namespaces in order to add a hierarchical structure. For example, you can define a namespace to include all controllers
/**
* #namespace MyApp.Controllers
*/
, and prefix all controller with MyApp.Controllers. You can also define namespaces like MyApp.Product or MyApp.Customer etc.
Although not perfect, I like using jsdoc to document angularjs codes because
It is simple;
The module-controller-function hierarchy are kept;
And it keeps jsdoc's merit that it is a browsable documentation site.
A table style jsdoc stylesheet:
Particularly, I've adapted the default jsdoc stylesheet to a table style like the Java API documentation. It looks clearer.
In Windows, I replace this file: C:\Users\user1\AppData\Roaming\npm\node_modules\jsdoc\templates\default\static\styles with this file https://github.com/gm2008/jsdoc/blob/master/templates/default/static/styles/jsdoc-default.css
That's it.
I have had to go down the route of creating the functions outside of the type above and calling those functions in such things as .run or factories etc.
/**
* #author Example <jon.doe#example.com>
* #copyright 2014 Example Ltd. All rights reserved.
*/
(function () {
window.example = window.example || {};
/**
* Example Namespace
* #memberOf example
* #namespace example.angular
*/
window.example.angular = window.example.angular || {};
var exAngular = window.example.angular;
/**
* My example bootstrap run function
* #param {object} $http {#link http://docs.angularjs.org/api/ng.$http}
* #param {[type]} $cookies {#link http://docs.angularjs.org/api/ngCookies.$cookies}
*/
var runFunction = function ($http, $cookies) {
$http.defaults.headers.post['X-CSRFToken'] = $cookies.csrftoken;
$http.defaults.headers.common['X-CSRFToken'] = $cookies.csrftoken;
};
/**
* A Example Angular Bootstrap Module
* #memberOf example.angular
* #namespace example.angular.bootstrap
* #function bootstrap
* #example
* <div ng-app="exampleAngularBootstrap">
* <div ng-view></div>
* </div>
*/
exAngular.bootstrap = angular.module('exampleAngularBootstrap', [
'ngRoute',
'ngResource',
'ngCookies'
])
.run(runFunction);
})();

What has happened to javascript helper in cakePHP 2?

I have used this item and get this error :
Missing Helper
Error: JavascriptHelper could not be found.
Error: Create the class JavascriptHelper below in file: app/View/Helper/JavascriptHelper.php
<?php
class JavascriptHelper extends AppHelper {
}
Well indeed, this file does not exists, and I tried to use 'Js' in my helper array.
class myClassController expend AppController {
var $helpers = array('Html', 'Js'); // and not 'Javascript');
In the code, the method $this->Javascript->codeBlock is called to add a javascript method (in the middle of the content instead of the header) but there is no $this->Js->codeBlockcodeBlock either.
$output .= $this->Js->codeBlock("datepick('" . $htmlAttributes['id'] . "','01/01/" . $options['minYear'] . "','31/12/" . $options['maxYear'] . "');");
Could you explain me what happened to the old Javascript helper or how to get the code working?
Is there an other helper which could work with CakePHP-2.0?
Cordially,
Have you read the migration guide? If not do that now:
http://book.cakephp.org/2.0/en/appendices/2-0-migration-guide.html#xmlhelper-ajaxhelper-and-javascripthelper-removed
XmlHelper, AjaxHelper and JavascriptHelper removed The AjaxHelper and
JavascriptHelper have been removed as they were deprecated in version
1.3. The XmlHelper was removed, as it was made obsolete and redundant with the improvements to Xml. The Xml class should be used to replace
previous usage of XmlHelper.
The AjaxHelper, and JavascriptHelper are replaced with the JsHelper
and HtmlHelper.
JsHelper JsBaseEngineHelper is now abstract, you will need to
implement all the methods that previously generated errors.
So
$this->Js->codeBlock('...');
is now
$this->Html->codeBlock('...');
HtmlHelper::scriptBlock($code, $options = array())
//Parameters:
$code (string) – The code to go in the script tag.
$options (array) – An array of html attributes.

Cakephp Localization, Cannot Change language when DEFAULT_LANGUAGE is set

I am confused :)
I'm using the p18n component in cakephp found here:
http://www.palivoda.eu/2008/04/i18n-in-cakephp-12-database-content-translation-part-2/
This component requires me to set in core.php the following constant:
define("DEFAULT_LANGUAGE", 'eng')
However when this is set I cannot change the language using:
Configure::write('Config.language', 'eng');
At the moment, into my knowledge, the only way to change the locale of my static content is the use of the Configure::write. But for the dynamic content to change through the use of the p28n component I must have the DEFINE_LANGUAGE constant set to a value.
This is all very confusing. Any help will be much appreciated.
I'm not familiar with particular component, but I've done this "manually" by setting the same constant in my app/config/bootstrap.php file and then setting the "actual" language to be used in my AppController (copied from the core code to app/app_controller.php). The appropriate snippets of that controller look like this:
uses ( 'L10n' );
class AppController extends Controller {
public function beforeFilter() {
$this->_setLanguage();
/**
* Set the default "domain" for translations. The domain is the
* same as the po file name in a given locale directory. e.g.
* __d ( 'homepage', 'message_id' ) would look for the
* message_id key in homepage.po. Using the __() convenience
* function will always look in default.po.
*/
$this->set ( 'domain', 'default' );
}
private function _setLanguage() {
$this->L10n = new L10n();
# Auto-detect the request language settings
$this->L10n->get();
}
}
Pretty vanilla stuff, but it works great. And breaking out the _setLanguage() method allows for the use of different methodologies to determine locale (e.g subdomain like fr.mydomain.com).

Resources