Rearrange common functions in specific order with PhpStorm - php

PhpStorm has a nice little rearrange feature, but I can't seem to get it to work.
I have a set of functions that my framework uses in every page. I want them to always be in the same order (and hopefully have 2 newlines between each one). For example:
class myClass {
function head() {}
function css() {}
function html() {}
function js() {}
}
I set up up my arrange tab under Settings > Editor > Code Style > PHP to look like this:
After doing this, clicking the Rearrange Code option still did nothing. I've also tried adding method to each one, like this:
It made no difference.
Is there a way to get PhpStorm to automatically rearrange functions in a user defined order (hopefully with 2 newlines in between each)?

You need to put the rules before the method - by modifiers (default) one.
This way, your methods will always come first and then PHPStorm will order the rest like it usually does. If they're at the end, all of the methods will already have been consumed by the default rule, so the remaining rules won't matter.
Also, you need to specify method as you did in your second example.
Then, using Rearrange Code should do it (I've just tested it).

Related

Latte - call function in TPL (ideally with parameter) instead of variable

I decided to rewrite an older website that I made years ago and use templating system. I decided to use Latte, as its generating PHP files, which makes it really fast compared to systems that parse tpl every time. But I was not able to figure out, how to call a function with latte and get its result.
I am used to our custom company TPL system which can call any function and even pass parameters to it just by calling {function_name.param} or use function constants with {function::param}.
Is something like this possible purely in Latte (I am not using Nette or any other framework)? I do not want to call every single function in PHP and add it to array of parameters that TPL has to its disposal. That just makes it slower (yep I know I could use ifs in there and then ifs in TPL, but that's also an useless code duplication).
I want it to be able to call a function within class that's rendering the TPL (or its parent classes OFC) and return its output when I need it (if I even do need it), so I can avoid unnecessary calls to functions when initializing parameters for TPL parsing.
I tried to google quite a lot, but I didn't find anything useful.
I should also mention, that I am not going to use any framework at all, except Latte with Tracy and Tester for automatic testing. I do not want to use Nette or Symfony 2 etc. as the site is not that big and using whole framework would just make it even more complicated than it needs to be.
Thanks.
.
Ps.: Could somebody create tag for Latte?
You can simply call any php function this way:
{? echo 'hello'}
or in newer versions of Latte:
{php echo 'hello'}
Also, you can pass instances of Nette\Utils\Html (small lib separated from framework, full of great tools even for small apps) which will be directly rendered.
Or if you want to use own class rendering output directly, simply implement __toString() function using IHtmlString interface:
class MyOwnClassRenderableByLatte implements \Latte\Runtime\IHtmlString
{
function __toString()
{
return 'Hi';
}
}
Template sample including your later questions:
{php
// You can instantiate needed classes in one synoptical block
// in the head of template file or reather instantiate them
// outside of template and pass them as template variables
$a = new ClassA();
$b = new ClassB();
}
<div>{$a->someFunction()}</div>
<div>
{* Or you can instantiate class inplace this way,
but I wouldn't recommend it. BTW: This is Latte comment.
*}
{php (new ClassC())->otherFunction()}
</div>
Try to use something like this, its same as with javascript
{some code} //is for latte expression
{ some other code} //with space after first bracket its no more latte expression
Not sure if your TPL will handle it, but you will see
If it will work, you can use more imagination and use something like
{
some fluffy code
}

Surrounding text with a method call

I have a class that has two methods that are used often:self::foo() and self::bar().
I would like to surround text, mainly variables in other methods. I can do comments, if/else, try/catch, etc, but I can't with arbitrary method calls.
I don't even know if PHPStorm does this, honestly. Does anyone know how to do this?
UPDATE
I would like to take this:
function func() {
return $variable;
}
and make it this:
function func() {
return self::foo($variable);
}
or
function func() {
return this->bar($variable);
}
You can create and use Live Template that will do what you want (surround current selection with predefined template): separate template for each method call.
http://confluence.jetbrains.com/display/PhpStorm/PhpStorm+Early+Access+Program -- the last section "Creating Surround Templates" is what you need in particular.
You can extract a function using WebStorm's refactoring tools.
Do do so, mark the code you want to have extracted and press Ctrl + Alt + M.
For more info, have a look at JetBrains' Website:
http://blog.jetbrains.com/webide/2011/05/extract-function-method-refactoring-for-php/
Edit: Thanks for the clarification. I am not aware of a refactoring tool that fulfills this particular need. However, if you have a lot of occurrences in one file, Search and Replace might be helpful.

Hooking into function calls in php

A little background: At runtime I would like to be able to inspect the currently called functions javadoc-style documentation, to determine its formal (typed) declaration. This would allow runtime type checking (for simple and complex types) by means of reflection (at a cost) during debugging and testing, something that I would find immensely helpful.
So, in php I would like for a user defined function to get called whenever any other function is about to get called. That is, if a function foo() gets called, I would like to have my callHookHandler() function called immediately before.
One solution would be to implement __call() in all user defined classes, but that is both unwieldy and doesn't include support for functions defined outside classes, so I am looking for a better solution.
This sounds a bit of a fun one so I'm going to give answering it a try.
I hope this helps you. Let me know how it goes.
So, what you are asking can be done, and here's how:
For Functions:
Get all defined functions with $function = get_defined_functions().
Loop through the $functions['user'] key and inspect each one with the ReflectionFunction class. You'll need to get:
The comment using ->getDocComment()
The arguments using ->getParameters()
Do some magic (I'll let you figure out how to parse the comment using some regular extressions and match it up with the parameter list from the reflection. Don't forget optional parameters!)
Rename the function using runkit_function_rename
Generate code in a string that checks the parameters and calls the renamed function
Generate a parameter list as a string
Create a new function with runkit_function_add using the code you generated in step #5 and the parameter list from step #6.
For Classes:
Get a list of classes with $classes = get_declared_classes();
Loop through each one and inspect it with ReflectionObject and ->getMethods() to get the methods. Make sure that the class is not internal with ->isInternal() because we can't do anything about the internal classes.
In an inner loop... go through each method using the ReflectionMethod class. Get the arguments and PHPDoc/JavaDoc comments just like you did with normal functions.
Do the same thing you did with the functions only use runkit_method_add and runkit_method_rename instead.
Downsides:
You won't be able to do the checking on internal class methods and functions (which is fine because they won't have doc comments anyway).
This is a lot of work! I left a lot of parts up to your imagination to avoid this being the length of a short book.
Please send me this or open source it and let me know when you finish, I really want to use this myself. Contact info is on my website which is in my profile ;)
Alternatively:
You can use XDebug's function trace along with reflection then analyze the results after the fact so that you don't have to dynamically edit the code. If you want to write unit-test you could even automate it.
Hope type checking makes it into future versions of PHP and wait: https://wiki.php.net/rfc/typechecking
Notes:
This class reference has a potentially useful example of parsing docComments in the comments section of the page:
http://us.php.net/manual/en/class.reflectionmethod.php
References
get_defined_functions
get_declared_classes
ReflectionFunction
ReflectionObject
ReflectionMethod
runkit
Alternative way to hook into function call is to use a trick with namespaces: Intercepting Execution of System Functions in PHP
You can also use the Go! framework to define an aspect to intercept the execution of system functions automatically.

Extracting function declarations from a PHP file

I'm looking to create an on-site API reference for my framework and application.
Basically, say I have a class file model.class.php:
class Model extends Object {
... code here ...
// Separates results into pages.
// Returns Paginator object.
final public function paginate($perpage = 10) {
... more code here ...
}
}
and I want to be able to generate a reference that my developers can refer to quickly in order to know which functions are available to be called. They only need to see the comments directly above each function and the declaration line. Something like this (similar to a C++ header file):
// Separates results into pages.
// Returns Paginator object.
final public function paginate($perpage = 10);
I've done some research and this answer looked pretty good (using Reflection classes), however, I'm not sure how I can keep the comments in.
Any ideas?
I want to keep the current comment formatting. Myself and the people who are working on the code hate the verbosity associated with PHPDocumentor. Not to mention a comment-rewrite of the entire project would take years, so I want to preserve just the // comments in plaintext.
Why don't you just run PHPDocumenter on the code?
PHPDoc is identical to JavaDoc, and will retain all the parameters and comments in the docblock above the function.
EDIT: Since you don't want PHPDoc, I think it would probably be easiest to write a RegEx parser to do it, since Reflection won't provide you with any surrounding comments.
PHP code to get the comment:
if(preg_match("#//(.+)$#",$line,$match)>0)
{
echo "Comment is: ".$match[1];
}
this is what phpdoc is for. you comment your code a specific way, following certain rules, and when you're done you run your code through a parser. It outputs exactly what you're looking for.

Is there anyway to get the order of the OOP method being called?

For example lets say I have a set of classes and methods to do so:
$obj->method1()->method2();
Is there anyway for method1() to know with in itself that its the first method being called or for method2 to know that its the last?
Some more details
I just want to be able to build a set of these calls so that it either returns an instance of itself if the call to the method isnt at the end of the chain or return something different if its at the end.
For example
$obj->method1()->method2(); #Here method 2 will return lets say a string.
$obj->method1()->method2()->method3(); #Since method2 isnt at the end of the chain, it should return an instance of itself (or another object) here so that the chain could continue.
EDIT: anyone whoz trying to do this - it is a bad design pattern.
This does seem to be a duplicate. Refer to this question for more answers.
Not out of the box, not even with a Stack trace.
I guess you could put something together using constants or global variables:
Don't try this at home!
$GLOBALS["chain"] = array();
$obj->method1()->method2(); // method1 adds member to $GLOBALS["chain"],
// array_push($GLOBALS["chain"], __FUNCTION__);
// method2 does the same...
print_r($GLOBALS["chain"]);
That would give you the full chain - not yet which one is the last one, to do that, you would have to pass a flag to method2().
But it would be horribly hacky and pollute your code.
Is there a specific reason you need this for?
All you could do is find out which methods have been called so far, by setting some kind of global state in the class. But you can't find out what methods are being called after a method, and you wouldn't be able to tell the difference between methods in one chain and methods in another:
$obj->m1()->m2();
$obj->m3(); // You would think that m1() and m2() came before this in the same chain
You would need to have a method at the end of each chain to clear the global state in the class.
Since it seems you need to see which method comes next in a chain, this won't work for you.
I would say that this is a really bad design pattern, at least for PHP (and every other language I've worked in). Each method should do one thing only. If you need a method to either return a string or an object depending on what you need it for later, you are doing something wrong.
Granted, I have done something like this before. It was a meta-information class for images submitted by users -- you could set it up like this:
$meta = new ImageMeta();
$meta->first_name("foo")->last_name("bar")->email("baz")->id("guid");
But, if you did this:
$meta->first_name();
it would return a string. The default value for the first parameter was NULL, and if the method got NULL, it returned a string. Otherwise it set (and escaped) an internal value and returned $this.
At first I thought it was kind of cool, but it turned out to be a mistake. I hate using that class now. Just make one method/function do one thing only and you will be much happier.
I don't think this is possible, no -- at least, I've never seen anything about this.
(Out of curiosity : why would you need that ? Maybe it would be possible to use onther solution to solve your actual problem ?)
The only way this is possible is to let the methods save some global state.
If both methods are in the same class, you could add a variable to the class and let each class set a unique value.
But the question is if this is desirable. This kind of behavior is often not very smart in the long run.

Categories