The problem
I'm working on a project, that has a lot of blade-files. But PhpStorm doesn't seem to play nice, with mixing <?php ... ?> and #php ... #endphp.
As you can see here, PhpStorm says that $position_link isn't defined, yet it is just a few lines above (this image serves the purpose of displaying the IDE-warnings/errors):
It's the same problem with $data, but as you can see, on line 98, it doesn't complain. Hmm!
The question
Ideally: How do I make PhpStorm understand this code better?
Next best thing: How do I hide these warnings?
Solution attempt 1: Blade Plugin
I can see that the plugin called 'Blade' is now bundled with PhpStorm.
Solution attempt 2: Googled around
I found a bunch of articles about this:
Type hinting works within php block but not in blade.
My comment: I guess this is the same issue. If PhpStorm thinks the variable doesn't exist, then I assume that it can't autocomplete it either. The solution on that article is to open a new issue. Both linked issues are incomplete.
Make variables autocomplete in the PhpStorm 9 for Blade templates
My comment: This was 6 years ago. I refuse to believe that nothing has happened on this area since. The marked solution is that it isn't supported. The most upvoted is to add this on the line before: #php /** #var $position_link #endphp. But it doesn't work. And even if it did - then it will bloat the code immensely.
Solution attempt 3: <?php instead of #php
I also tried changing this:
#php
$position_link = 'left';
if( App\isset_with_value( $data, 'position_link' ) ){
$position_link = $data->position_link;
}
#endphp
<div class="links-wrapper" style='text-align: {{ $position_link }};'>
with this:
<?php
$position_link = 'left';
if( App\isset_with_value( $data, 'position_link' ) ){
$position_link = $data->position_link;
}
?>
<div class="links-wrapper" style='text-align: {{ $position_link }};'>
... But is still shows the error.
Solution attempt 4: Remove Blade completely
If I just write the whole thing in good ol' PHP, then I get a stylelint error:
I know this is another problem, which has to be solved in my Stylelint-settings. I figured I'd just show that this isn't a solution (for me) either.
My system specs
MacBook Pro 16-inch, 2019
OS: Big Sur, 11.6
PhpStorm version: 2021.2.2 - PS-212.5284.49
Related
I just installed Twitter Typeahead (older vesion 0.9.3).
Right now it links to a search.php page which queries the MySQL database to get the results. It gets the results I need, however, when I select the results, I can't figure out how to pass the ID or other information create a link to another page.
Here is the function in the HTML page that's calling the search.php page:
<script>
$(document).ready(function(){
$('input.typeahead').typeahead({
name: 'typeahead',
remote:'search.php?key=%QUERY',
limit : 10
});
});
</script>
Then search.php is called which queries the database correctly and gets the results I need:
<?php
$key=$_GET['key'];
$array = array();
$con=mysql_connect("hostname","username","password");
$db=mysql_select_db("databasename",$con);
$query=mysql_query("select * from customers where clientDisplayName LIKE '%{$key}%' OR clientPhNumber LIKE '%{$key}%' OR clientAltPhNumber LIKE '%{$key}%'");
while($row=mysql_fetch_assoc($query))
{
//$array[] = "<a href='customer-details.php?cid=".$row['id'] ."'><tr><td>" . $row['clientDisplayName'] . "</tr></td></a>";
$array[] = $row['clientDisplayName'];
}
echo json_encode($array);
?>
You can see the comment there, if I use that instead of the array that's uncommented, It will create a link as I desire, however.. it's buggy that way.
By Buggy I mean:
I HAVE to click on the actual text instead of anywhere in the result row
I cannot simply arrow-down and hit enter to select a response (it must be mouse clicked)
and even if it is clicked with the mouse, I can see the whole
Any ideas on what I can do here?
Do not use twitter typeahead. It is abandoned, no longer maintained, it has 250 issues, some of them very serious regarding basic behavior and severe bugs. I would recommend github.com/bassjobsen/Bootstrap-3-Typeahead instead.
I miss 'for' live template in PhpStorm: for($i = 0 ; $i < 5 ; $i++){ ... }. - Has anybody managed to create an appropriate one? - Like 'fore' or 'forek' ?
It's very strange, that unlike Intellij IDEA there is no such official live template in PhpStorm...
Sorry for digging this up, but since I've stumpled upon it coming from google, other people might as well.
The template from OP is correct. For clarity, here with nice formatting and without the leading "int":
for($ITERABLE$ = 0; $ITERABLE$ < $LIMIT$; $ITERABLE$++) {
$END$
}
To get it to work, you have to define it as PHP template:
When defining the template in File > Settings > Live Templates, below the actual template text, there is red text: No applicable contexts yet.
Click on the blue "Change", set it to php and everything is fine.
I am trying to get the html of top.links using the following ways:
$blockHtml = Mage::getModel('cms/block')->getBlockHtml('top.links')
$blockHtml = Mage::app()->getLayout()->getBlock('top.links').toHtml()
$blockHtml = Mage::getSingleton('core/layout')->getBlock('top.links')->toHtml()
None of above is working for me, how I can do this?
Thanks.
UPDATE
I used
$layout = Mage::getSingleton('core/layout');
$block = $layout->createBlock('page/html')->setTemplate('page/html/top.links.phtml')->toHtml();
With the help of this question Add Top Links on condition basis in magento but still no luck. During this try I found that the use of top.links.phtml is deprecated, any idea which template should I use for the links?
I think there is some dependency for top.links.phtml file, that's why it isn't working, when I tried to get footer.phtml it worked perfectly with above method.
Just like the op, I tried many ways without success. The following simple line finally does it:
<?php echo $this->getLayout()->getBlock('top.links')->toHtml(); ?>
Wow! I was able to find a correct answer finally :) Load block outside Magento, and apply current template
So by following the the above question's answer, I did this to get generated top.links
$layout = Mage::app()->getLayout();
$layout->getUpdate()
->addHandle('default')
->load();
$layout->generateXml()
->generateBlocks();
echo $layout->getBlock('top.links')->toHtml();
If you have created CMS block named 'block_identifier' from admin panel. Then following will be code to call them in .phtml
<?php echo $this->getLayout()->createBlock('cms/block')->setBlockId('block_identifier')->toHtml();
?>
Please,used the belowCodes.This will be working
echo $this->getLayout()->getcreateBlock('page/template_links')->toHtml();
I've come across multiple solutions that all use filters and hooks to prevent tinymce from stripping certain elements from within the post editor 'visual' editor.
I have a plugin that allows the user to place custom <span></span> tags into a new post, but when the user switches over to the 'visual' tab, tinymce then deletes the span tags they have placed.
I have one function here that is from 2009, which doesn't seem to work.
function my_change_mce_options( $init ) {
// Command separated string of extended elements
$ext = 'span[id|name|class|style]';
// Add to extended_valid_elements if it alreay exists
if ( isset( $init['extended_valid_elements'] ) ) {
$init['extended_valid_elements'] .= ',' . $ext;
} else {
$init['extended_valid_elements'] = $ext;
}
// Super important: return $init!
return $init;
}
add_filter('tiny_mce_before_init', 'my_change_mce_options');
I tried adding that to my plugins core files, but does not work. Apparently the newer version of tinymce doesn't do this, but WordPress 3.7.1 is still using an older version for stability reasons I guess.
Any ideas?
Upgrade to Version 4, its confirmed that the bug doesn't exist in that one.
I'm new to PHPUnit, and I'm having some trouble with unit testing HTML output.
My test follows:
/**
* #covers Scrap::removeTags
*
*/
public function testRemoveTags() {
// Variables
$simple_parameter = 'script';
$array_parameter = array('script', 'div');
$html = '<div class="pubanunciomrec" style="background:#FFFFFF;"><script type="text/javascript"><!-- google_ad_slot = "9853257829"; google_ad_width = 300; google_ad_height = 250; //--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script></div><table></table>';
// Expected HTML
$expected_html_whitout_script = new DOMDocument;
$expected_html_whitout_script->loadHTML('<div class="pubanunciomrec" style="background:#FFFFFF;"></div><table></table>');
$expected_html_without_script_div = new DOMDocument;
$expected_html_without_script_div->loadHTML('<table></table>');
// Actual HTML
$actual_whitout_script = new DOMDocument;
$actual_whitout_script->loadHTML($this->scrap->removeTags($html, $simple_parameter));
$actual_without_script_div = new DOMDocument;
$actual_without_script_div->loadHTML($this->scrap->removeTags($html, $array_parameter));
// Test
$this->assertEquals($expected_html_whitout_script, $actual_whitout_script);
$this->assertEquals($expected_html_without_script_div, $actual_without_script_div);
}
My problem is that the DOMDocument object generates some HTML code and I can't compare it. How can I print the DOMDocument object to see the output? Any clues on how to compare the HTML?
Sorry for my bad english.
Best Regards,
Since 2013, there is another way to test HTML Output using PHPUnit.
It is using assertTag() method that can be found in PHPUnit 3.7 and 3.8.
For example :
// Matcher that asserts that there is an element with an id="my_id".
$matcher = array('id' => 'my_id');
// Matcher that asserts that there is a "span" tag.
$matcher = array('tag' => 'span');
// Matcher that asserts that there is a "div", with an "ul" ancestor and a "li"
// parent (with class="enum"), and containing a "span" descendant that contains
// an element with id="my_test" and the text "Hello World".
$matcher = array(
'tag' => 'div',
'ancestor' => array('tag' => 'ul'),
'parent' => array(
'tag' => 'li',
'attributes' => array('class' => 'enum')
),
'descendant' => array(
'tag' => 'span',
'child' => array(
'id' => 'my_test',
'content' => 'Hello World'
)
)
);
// Use assertTag() to apply a $matcher to a piece of $html.
$this->assertTag($matcher, $html);
Read more in official PHPUnit Website.
You may want to consider looking at Selenium. It is a browser-based testing tool for doing functional tests for a web site.
You write scripts which involve loading a web browser and simulating clicks and other actions, and then doing asserts to check that, for example, specific page elements are present, in the correct place or contain the expected values.
The tests can be written using an IDE that runs as a plug-in for Firefox, but they can be run against all the major browsers.
We have a suite of Selenium tests that run as part of our CI process, allowing us to see very quickly if something has gone wrong with our HTML output.
All in all, its a very powerful testing tool.
Also, it integrates with PHPUnit (and other language-specific tools), so it does answer your question, although probably not in the way you were thinking of.
You should be a bit careful in comparing outputted HTML to a correct template. Your HTML will change a lot, and you can end up spending too much time on maintaining your tests.
See this post for an alternative approach.
You can use saveHtml method of DOMDocument and compare the output.
You can compare two HTML strings with PHPUnit assertXmlStringEqualsXmlString method:
$this->assertXmlStringEqualsXmlString($emailMarkup, $html);
where
$emailMarkup - expected HTML string
$html - current HTML string
Important! HTML strings must be XML-valid. For example use
<br/>
instead
<br>
Also tag attributes must have values, e.g. use
<hr noshade="true">
instead
<hr noshade>
It is best not to validate against a template (unless you want to make sure nothing changes, but that is a different condition / test that you may want). You will probably want to test that your HTML includes what the user should actually see, and not that the actual HTML that formats the output is exactly what is in a template. I would recommend sending your HTML through a converter that changes it into pure text, then testing to see if you get the right results. This accommodates future functionality and data related changes that are inevitable in software development. You don't want your tests failing because someone added a class somewhere. This is probably a custom type test you will want to code yourself to meet your needs.
It is also best to insure your HTML (and CSS) is correctly formatted, what ever it may be. Sometimes invalid HTML is parsed and displayed somewhat reasonably by the browser, but best not to rely on browsers knowing what do to with invalid HTML and CSS. I have seen many issues fixed just by correcting the HTML.
I developed a library that outputs HTML PHPFUI, and I could not find any recent or even supported HTML unit tests for PHPUnit. So I created https://packagist.org/packages/phpfui/html-unit-tester which is a modern HTML and CSS unit tester. It validates against w3.org standards, so will always be up to date with the latest.
Basically you can pass in HTML fragments, or entire pages, and it will check validity of your HTML. You can test strings, files or even live URLs. Really handy to make sure all the HTML and CSS you are generating is valid. I found so many issues with my code with this library, was definitely worth the time invested. Hope everyone can benefit from it as well.