Love Fuel?    Donate

FuelPHP Forums

Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
Functions code completion on NetBeans (and also PhpStorm)
  • I use NetBeans 7.1 (latest version) and I searched way to code completion for functions of FuelPHP class. NetBeans pick up fucntions when I start to type a few lettes of class name, so completion for class name work well with class name. But after typed class name, and '::', nothing happen. no code complete. OK, I knew the way to declare class like 'class View extends Fuel\Core\View { }' for all class of core and package (and my code that used namespace). I have made code generator for code complition now. This work as FuelPHP task. ccc.php
    <?php
    
    namespace Fuel\Tasks;
    
    /**
     *
     * Code Completion Code Generator
     *
     */
    class Ccc
    {
    
        private static $without_dirs;
        private static $generated_code = array();
        private static $dup_class = array();
    
        public static function run()
        {
            // keep without-genereted directory names
            if (\Cli::option('without', false) or \Cli::option('WITHOUT', false))
            {
                self::$without_dirs = explode('+', \Cli::option('without'));
            }
            else
            {
                self::$without_dirs = false;
            }
    
            // other command line handling to generate
            if (\Cli::option('all', false) or \Cli::option('ALL', false))
            {
                $dir = \File::read_dir(COREPATH, 0, 'php');
                self::generate_redefine($dir, '', COREPATH);
                $dir = \File::read_dir(APPPATH, 0, 'php');
                self::generate_redefine($dir, '', APPPATH);
                $dir = \File::read_dir(PKGPATH, 0, 'php');
                self::generate_redefine($dir, '', PKGPATH);
            }
            else
            {
                if (\Cli::option('core', false) or \Cli::option('CORE', false))
                {
                    $dir = \File::read_dir(COREPATH, 0, 'php');
                    self::generate_redefine($dir, '', COREPATH);
                }
                elseif (\Cli::option('app', false) or \Cli::option('APP', false))
                {
                    $dir = \File::read_dir(APPPATH, 0, 'php');
                    self::generate_redefine($dir, '', APPPATH);
                }
                elseif (\Cli::option('packages', false) or \Cli::option('PACKAGES', false))
                {
                    $dir = \File::read_dir(PKGPATH, 0, 'php');
                    self::generate_redefine($dir, '', PKGPATH);
                }
                else
                {
                    echo PHP_EOL.'usage: [php] oil [-all] [-core] [-app] [-packages] [-without=directory_name[+directory_name]...] [-help]'.PHP_EOL;
                    echo 'Code Completion Code Generator for FuelPHP'.PHP_EOL.PHP_EOL;
                    echo 'php at head of commnad line needed if you use oil in cmd.exe on windows normaly.'.PHP_EOL;
                    echo '-all : Generate from app, core and packages directory.'.PHP_EOL;
                    echo '-app : Generate from app directory.'.PHP_EOL;
                    echo '-core : Generate from core directory.'.PHP_EOL;
                    echo '-help : Display this help and exit.'.PHP_EOL;
                    echo '-packages : Generate from core packages.'.PHP_EOL;
                    echo '-without : + seperated directory name where no generated code.'.PHP_EOL.PHP_EOL;
                    echo 'This task output result into standard output.'.PHP_EOL;
                    echo 'So after you checked output code, redirect to your output PHP file. Do like :'.PHP_EOL;
                    echo 'php oil r ccc -all -without=tasks+migrations+vendor+tests+oil+orm+parser > CodeCompetionCode.php'.PHP_EOL;
                    echo 'And put the file on anywhere your source code folder.'.PHP_EOL.PHP_EOL;
                    echo 'Caution:'.PHP_EOL;
                    echo 'This generated code work on no namespace used on your code in IDE editor.'.PHP_EOL;
                    echo 'Because this just redefine every short class name as general(top) level of namespace.'.PHP_EOL;
                    echo 'So never work at a code like a task and/or a package, that used namespace.(Or your code used namespace. ;) )'.PHP_EOL;
                    echo 'If you want to work code completion on code used namespace, it is the better way switch comment off for the namespace statement during you edit it.';
                    exit(0);
                }
            }
    
            ksort(self::$generated_code);
            ksort(self::$dup_class);
    
            echo '<?php'.PHP_EOL;
            if (!empty(self::$dup_class))
            {
                echo '// Duplicated classes from here'.PHP_EOL;
                echo implode("\n", self::$dup_class);
                echo PHP_EOL.'// Duplicated classes to here'.PHP_EOL;
            }
            echo implode("\n", self::$generated_code);
        }
    
        private static function generate_redefine($ary, $path, $base)
        {
            foreach ($ary as $key => $val)
            {
                if (is_array($val))
                {
    
                    if ((self::$without_dirs and !in_array(trim($key, '/\\'), self::$without_dirs)) or !self::$without_dirs)
                    {
                        self::generate_redefine($val, $path.$key, $base);
                    }
                }
                else
                {
                    // read php code
                    try
                    {
                        $buff = explode("\n", \File::read($base.$path.$val, true));
                    }
                    catch (\Fuel\Core\InvalidPathException $e)
                    {
                        die('Failed to read file : '.$path.$val);
                    }
    
                    $namespace = '';
    
                    foreach ($buff as $i)
                    {
                        // get namespace
                        if (preg_match('/^[ \\t]*namespace[ \\t]+(.+?)[ \\t]*;/', $i, $matched) === 1)
                        {
                            $namespace = $matched[1];
                        }
                        // get abstract class
                        elseif ($namespace != '' and preg_match('/^[ \\t]*abstract[ \\t]+class[ \\t]+(\\w+)/', $i, $matched) === 1)
                        {
                            self::reg_classname($matched[1],
                                "abstract class\t".$matched[1].' extends '.$namespace.'\\'.$matched[1].'{};');
                        }
                        // get interface
                        elseif ($namespace != '' and preg_match('/^[ \\t]*interface[ \\t]+(\\w+)/', $i, $matched) === 1)
                        {
                            self::reg_classname($matched[1],
                                "interface\t\t".$matched[1].' extends '.$namespace.'\\'.$matched[1].'{};');
                        }
                        // get class
                        elseif ($namespace != '' and preg_match('/^[ \\t]*class[ \\t]+(\\w+)/', $i, $matched))
                        {
                            self::reg_classname($matched[1],
                                "class\t\t\t".$matched[1].' extends '.$namespace.'\\'.$matched[1].'{};');
                        }
                    }
                }
            }
        }
    
        private static function reg_classname($key, $str)
        {
            if (key_exists($key, self::$generated_code))
            {
                self::$dup_class[$key] = $str;
            }
            else
            {
                self::$generated_code[$key] = $str;
            }
        }
    
    }
    

    on windows, open cmd.exe , type 'php oil r ccc' to help. On linux, open terminal , type 'oil r ccc' to help. (I didn't test this code on linux. ) The best and simplest way to use this, 'php oil -all -without=tasks+migrations+vendor+tests+oil+orm+parser' and check output. When no proble on generated code, redirect it php file like 'php oil -all -without=tasks+migrations+vendor+tests+oil+orm+parser > CodeCompletionCode.php' As you know, you can put this code anywhere under sorce code folder on your project. If you use NetBeans, can put it into nbproject directory, it is default general include folder. If you can't use oil well, use this code for FuelPHP 1.1. But the best way is run this on your FuelPHP installed environment.
    <?php
    class           Agent extends Fuel\Core\Agent{};
    class           Arr extends Fuel\Core\Arr{};
    class           Asset extends Fuel\Core\Asset{};
    class           AttachmentNotFoundException extends Email\AttachmentNotFoundException{};
    class           Auth extends Auth\Auth{};
    class           AuthException extends Auth\AuthException{};
    abstract class  Auth_Acl_Driver extends Auth\Auth_Acl_Driver{};
    class           Auth_Acl_SimpleAcl extends Auth\Auth_Acl_SimpleAcl{};
    abstract class  Auth_Driver extends Auth\Auth_Driver{};
    abstract class  Auth_Group_Driver extends Auth\Auth_Group_Driver{};
    class           Auth_Group_SimpleGroup extends Auth\Auth_Group_SimpleGroup{};
    abstract class  Auth_Login_Driver extends Auth\Auth_Login_Driver{};
    class           Auth_Login_SimpleAuth extends Auth\Auth_Login_SimpleAuth{};
    class           Autoloader extends Fuel\Core\Autoloader{};
    class           Cache extends Fuel\Core\Cache{};
    class           CacheExpiredException extends Fuel\Core\CacheExpiredException{};
    class           CacheNotFoundException extends Fuel\Core\CacheNotFoundException{};
    interface       Cache_Handler_Driver extends Fuel\Core\Cache_Handler_Driver{};
    class           Cache_Handler_Json extends Fuel\Core\Cache_Handler_Json{};
    class           Cache_Handler_Serialized extends Fuel\Core\Cache_Handler_Serialized{};
    class           Cache_Handler_String extends Fuel\Core\Cache_Handler_String{};
    class           Cache_Storage_Apc extends Fuel\Core\Cache_Storage_Apc{};
    abstract class  Cache_Storage_Driver extends Fuel\Core\Cache_Storage_Driver{};
    class           Cache_Storage_File extends Fuel\Core\Cache_Storage_File{};
    class           Cache_Storage_Memcached extends Fuel\Core\Cache_Storage_Memcached{};
    class           Cache_Storage_Redis extends Fuel\Core\Cache_Storage_Redis{};
    class           Cli extends Fuel\Core\Cli{};
    class           Config extends Fuel\Core\Config{};
    class           ConfigException extends Fuel\Core\ConfigException{};
    abstract class  Config_File extends Fuel\Core\Config_File{};
    class           Config_Ini extends Fuel\Core\Config_Ini{};
    interface       Config_Interface extends Fuel\Core\Config_Interface{};
    class           Config_Json extends Fuel\Core\Config_Json{};
    class           Config_Php extends Fuel\Core\Config_Php{};
    class           Config_Yml extends Fuel\Core\Config_Yml{};
    abstract class  Controller extends Fuel\Core\Controller{};
    abstract class  Controller_Rest extends Fuel\Core\Controller_Rest{};
    abstract class  Controller_Template extends Fuel\Core\Controller_Template{};
    class           Cookie extends Fuel\Core\Cookie{};
    class           Crypt extends Fuel\Core\Crypt{};
    class           DB extends Fuel\Core\DB{};
    class           DBUtil extends Fuel\Core\DBUtil{};
    abstract class  Database_Connection extends Fuel\Core\Database_Connection{};
    class           Database_Exception extends Fuel\Core\Database_Exception{};
    class           Database_Expression extends Fuel\Core\Database_Expression{};
    class           Database_MySQL_Connection extends Fuel\Core\Database_MySQL_Connection{};
    class           Database_MySQL_Result extends Fuel\Core\Database_MySQL_Result{};
    class           Database_MySQLi_Connection extends Fuel\Core\Database_MySQLi_Connection{};
    class           Database_MySQLi_Result extends Fuel\Core\Database_MySQLi_Result{};
    class           Database_PDO_Connection extends Fuel\Core\Database_PDO_Connection{};
    class           Database_Query extends Fuel\Core\Database_Query{};
    abstract class  Database_Query_Builder extends Fuel\Core\Database_Query_Builder{};
    class           Database_Query_Builder_Delete extends Fuel\Core\Database_Query_Builder_Delete{};
    class           Database_Query_Builder_Insert extends Fuel\Core\Database_Query_Builder_Insert{};
    class           Database_Query_Builder_Join extends Fuel\Core\Database_Query_Builder_Join{};
    class           Database_Query_Builder_Select extends Fuel\Core\Database_Query_Builder_Select{};
    class           Database_Query_Builder_Update extends Fuel\Core\Database_Query_Builder_Update{};
    abstract class  Database_Query_Builder_Where extends Fuel\Core\Database_Query_Builder_Where{};
    abstract class  Database_Result extends Fuel\Core\Database_Result{};
    class           Database_Result_Cached extends Fuel\Core\Database_Result_Cached{};
    class           Database_Transaction extends Fuel\Core\Database_Transaction{};
    class           Date extends Fuel\Core\Date{};
    class           Debug extends Fuel\Core\Debug{};
    class           Email extends Email\Email{};
    class           EmailSendingFailedException extends Email\EmailSendingFailedException{};
    class           EmailValidationFailedException extends Email\EmailValidationFailedException{};
    abstract class  Email_Driver extends Email\Email_Driver{};
    class           Email_Driver_Mail extends Email\Email_Driver_Mail{};
    class           Email_Driver_Sendmail extends Email\Email_Driver_Sendmail{};
    class           Email_Driver_Smtp extends Email\Email_Driver_Smtp{};
    class           Error extends Fuel\Core\Error{};
    class           Event extends Fuel\Core\Event{};
    class           Fieldset extends Fuel\Core\Fieldset{};
    class           Fieldset_Field extends Fuel\Core\Fieldset_Field{};
    class           File extends Fuel\Core\File{};
    class           FileAccessException extends Fuel\Core\FileAccessException{};
    class           File_Area extends Fuel\Core\File_Area{};
    class           File_Handler_Directory extends Fuel\Core\File_Handler_Directory{};
    class           File_Handler_File extends Fuel\Core\File_Handler_File{};
    class           Finder extends Fuel\Core\Finder{};
    class           Form extends Fuel\Core\Form{};
    class           Format extends Fuel\Core\Format{};
    class           Ftp extends Fuel\Core\Ftp{};
    class           FtpConnectionException extends Fuel\Core\FtpConnectionException{};
    class           FtpFileAccessException extends Fuel\Core\FtpFileAccessException{};
    class           Fuel extends Fuel\Core\Fuel{};
    class           FuelException extends Fuel\Core\FuelException{};
    class           Fuel_Exception extends Fuel\Core\Fuel_Exception{};
    class           Html extends Fuel\Core\Html{};
    abstract class  HttpException extends Fuel\Core\HttpException{};
    class           HttpNotFoundException extends Fuel\Core\HttpNotFoundException{};
    class           HttpServerErrorException extends Fuel\Core\HttpServerErrorException{};
    class           Image extends Fuel\Core\Image{};
    abstract class  Image_Driver extends Fuel\Core\Image_Driver{};
    class           Image_Gd extends Fuel\Core\Image_Gd{};
    class           Image_Imagemagick extends Fuel\Core\Image_Imagemagick{};
    class           Image_Imagick extends Fuel\Core\Image_Imagick{};
    class           Inflector extends Fuel\Core\Inflector{};
    class           Input extends Fuel\Core\Input{};
    class           InvalidAttachmentsException extends Email\InvalidAttachmentsException{};
    class           InvalidEmailStringEncoding extends Email\InvalidEmailStringEncoding{};
    class           InvalidPathException extends Fuel\Core\InvalidPathException{};
    class           Lang extends Fuel\Core\Lang{};
    class           Log extends Fuel\Core\Log{};
    class           Markdown extends Fuel\Core\Markdown{};
    class           Migrate extends Fuel\Core\Migrate{};
    class           Model extends Fuel\Core\Model{};
    class           Model_Crud extends Fuel\Core\Model_Crud{};
    class           Mongo_Db extends Fuel\Core\Mongo_Db{};
    class           Mongo_DbException extends Fuel\Core\Mongo_DbException{};
    class           Num extends Fuel\Core\Num{};
    class           OutsideAreaException extends Fuel\Core\OutsideAreaException{};
    class           Package extends Fuel\Core\Package{};
    class           PackageNotFoundException extends Fuel\Core\PackageNotFoundException{};
    class           Pagination extends Fuel\Core\Pagination{};
    class           Profiler extends Fuel\Core\Profiler{};
    class           Redis extends Fuel\Core\Redis{};
    class           RedisException extends Fuel\Core\RedisException{};
    class           Request extends Fuel\Core\Request{};
    class           Request404Exception extends Fuel\Core\Request404Exception{};
    class           RequestException extends Fuel\Core\RequestException{};
    class           Request_Curl extends Fuel\Core\Request_Curl{};
    abstract class  Request_Driver extends Fuel\Core\Request_Driver{};
    class           Request_Soap extends Fuel\Core\Request_Soap{};
    class           Response extends Fuel\Core\Response{};
    class           Route extends Fuel\Core\Route{};
    class           Router extends Fuel\Core\Router{};
    class           Security extends Fuel\Core\Security{};
    class           SendmailConnectionException extends Email\SendmailConnectionException{};
    class           SendmailFailedException extends Email\SendmailFailedException{};
    class           Session extends Fuel\Core\Session{};
    class           Session_Cookie extends Fuel\Core\Session_Cookie{};
    class           Session_Db extends Fuel\Core\Session_Db{};
    abstract class  Session_Driver extends Fuel\Core\Session_Driver{};
    class           Session_Exception extends Fuel\Core\Session_Exception{};
    class           Session_File extends Fuel\Core\Session_File{};
    class           Session_Memcached extends Fuel\Core\Session_Memcached{};
    class           Session_Redis extends Fuel\Core\Session_Redis{};
    class           SimpleUserUpdateException extends Auth\SimpleUserUpdateException{};
    class           SimpleUserWrongPassword extends Auth\SimpleUserWrongPassword{};
    class           SmtpAuthenticationFailedException extends Email\SmtpAuthenticationFailedException{};
    class           SmtpCommandFailureException extends Email\SmtpCommandFailureException{};
    class           SmtpConnectionException extends Email\SmtpConnectionException{};
    class           Str extends Fuel\Core\Str{};
    class           TestCase extends Fuel\Core\TestCase{};
    class           Theme extends Fuel\Core\Theme{};
    class           ThemeException extends Fuel\Core\ThemeException{};
    class           Unzip extends Fuel\Core\Unzip{};
    class           Upload extends Fuel\Core\Upload{};
    class           Uri extends Fuel\Core\Uri{};
    class           Validation extends Fuel\Core\Validation{};
    class           Validation_Error extends Fuel\Core\Validation_Error{};
    class           View extends Fuel\Core\View{};
    abstract class  ViewModel extends Fuel\Core\ViewModel{};
    
  • Thanks for your ccc.php, it works fine with Netbeans 7.1.2. :] Does someone has a trick to get CTRL+click functional ?
  • For some reason I'm not getting any code completion in netbeans 7.1 :( I added your file, but I had to modify the "Fuel\Core" namespace to "\Fuel\Core" for completion to start working. Even then, it was only working when I was in the root "\" namespace. I had no completion when working on a package within it's own namespace. This appears to be an issue with Netbeans 7.1 completion because in 7.01 it's working perfectly (even without your file).
  • Hi 7.1 have bug on code completion about namespace. When you type namespace with class like \Fuel\Core\Validation::, function names complete normally, but nothing happen. And you had mentioned, in namespace like 'namespace AAA/BBB;' and typed '\Validation::', function names on completion list normally, but nothing happen. I asked about both in NetBeans Bugzilla, it was bugs and fixed in dev. version already. So on next version, it work properly. (I had checked both on dev. version, work well now) And 7.0.1 is very usefule(useful). I know it never think about namespace context deeply. So it complete a lot of items without context. I love it. But I asked about it also. NetBeans' completion think about namespace the user editing. So maybe 7.0.1 didn't work correctly. It is good for FuelPHP usres, but not good for other users. It show too much items for completion. (But in honesty, I love 7.0.1 working, like you. If you can, you put this completion optional new future as request into NetBeans' Bugzilla. As you read, I'm not good English writer, so I can't explain what is benefit for users. If requested, let me know. I post 'agree' with your idea.) I knew your discontents about NetBeans. I have same, so did something like this. And NetBeans community accept bug report and futures request. So try it. And some tips for NetBeans users...(not only you, natanv) 1. If you change namespace in Code Completion Code php file, back to original AAA\BBB, not \AAA\BBB.
    2. In your code, if exist like 'namespace \YOUR\NAMESPACE;', change 'namespace YOUR/NAMESPACE;'
    3. Tools->Options->Editor->Code Completion->Language:'PHP', and select 'Smart(M)' something(I use Japanese version, I don't know exact English strings)
    4. Now try this. Type 'Vi...' and come up CC window, select 'View' class of generated php file, don't select Fuel/Core or Parser namespace(display on right side).
    On namespace '\' (without namespace), it insert 'View'. And in like AAA\BBB namespace, it insert '\View'. It work properly. (Sorry, it will also not work on 7.1...) One more... Like this situation... $val = Validation::forge();
    $val->// no complition here... Yes, IDE don't know $val is a Validation class instance. If code '$val = new Validation();', IDE can understand, but it is not Fuel way. (If @return as PHPDoc comment is there, IDE can understand. For most of functions can use this if developers add this. But it is not simple. Some function possible return some classes, not only one.) You can add a line just before 1st line, like:
    </* @var $val Validation *>
    And IDE understand $val is Validation class instance, and completion work. On NetBeans, already set code template for this, type vdoc and <tab>, it will extend and set variable name. You just type class name and Enter key. If you hard type same variable and class name twice, use code template of NetBeans. Decide your short name, and template code is:
    </* @var $$${VAR} ${CLASS} *>
    $$${VAR} = ${CLASS}::${cursor}
    Then you just type your short name<tab>variable name<tab>class name<Enter> If you have good idea, let's me know.
  • Thank you for the explanation Hiro! I was able to make the code completion work a little better in netbeans 7.01 using your file. It's unfortunate that it doesn't work in 7.1. I think it has something to do with the fact that php resolves namespaces dynamically which could mean that the namespace context is not being properly determined by netbeans. I'll make a feature request to see if they can add a feature that would allow us to choose the desired namespace for code completion (just like 7.01). Another option would be if we could specify namespace aliases manually. This would be better: For example: Set "\" to "\Fuel\Core". Or \ to \MyPackage. Once I post the request, I'll add a link to it here so that we can all support it and make it more of a priority. (That way we con't be stuck with 7.01 forever ;) Also thanks for the idea of using the code templates to manually specify variable types in the code. I had been using the @return param in doc block to specify the returned objects for netbeans autocomplete but never thought of creating a template to manually set or override the type. Natan
  • As you mentioned, add @return is good way. I had explained about it in my Japanese blog, already, but not here. And I did request 2 things to NetBeans' developper. http://netbeans.org/bugzilla/show_bug.cgi?id=207802
    http://netbeans.org/bugzilla/show_bug.cgi?id=207803 If you love them, please 'agree' post to them. And add more your idea and explain. ML HiroKws
  • And my code template is here: https://github.com/HiroKws/FuelPHP_1_1_NetBeans_code_template_ja I hope it help to you.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion