Get at a categories image in PHP | Magento2 - php

I am trying to get at a categories image from within PHP / a .phtml file.
Here is my code:
$_category = $this->getCurrentCategory();
$_children = $_category->getChildrenCategories();
foreach( $_children as $child ){
if( $child->getIsActive() ){
echo "<p>" . $child->getImageUrl() . "</p>";
This last line results in an empty string. When I var_dump it, I get the following:
bool(false)
Upon further investigation, this getImageUrl function is defined in /vendor/magento/module-catalog/Model/Category.php on line 656, like so:
public function getImageUrl(){
$url = false;
$image = $this->getImage();
if ($image) {
The problem here is that $this->getImage() returns NULL. Nowhere in Category.php can I find the function getImage, and all of this makes me think that there is no getImage function in the Category class.
Is this correct? Do we need to add a getImage method to the class to make getImageUrl work?
Or is getImage inherited from elsewhere? And in this case, why is it returning NULL?
Disclaimers:
This is Magento 2.0.2.
I am not about to alter core code, I already have a theme of my own, and if I was to add a new function to the Category class I would extend the core code in my theme.
I have re-indexed, I have cleared caches, I have re-deployed.

Related

TYPO3 v8. Override function in Core class

I need to override the function
protected function getLanguageParameter()
{
$states = $this->getBackendUser()->uc['moduleData']['web_view']['States'];
$languages = $this->getPreviewLanguages();
$languageParameter = '';
if (isset($states['languageSelectorValue']) && isset($languages[$states['languageSelectorValue']])) {
$languageParameter = '&L=' . (int)$states['languageSelectorValue'];
}
$languageParameter = '&L=1';
return $languageParameter;
}
in the class TYPO3\CMS\Viewpage\Controller\ViewModuleController. It get called when you are open the View in the backend.
Lets say I would extend the class in my own extension. I already need a Hook that calls the function?
But how can I get that hook?
If the function has no hook yet you can try to insert it: make a patch and wait for it to become merged.
As 8 LTS already receives only 'priority bugfixes' it probably will not get merged.
The other way would be XClassing.

Get instances to arbitrary plugins in php files

The name is quite bad, but I really don't know what else to call it.
I'm trying to make a extendable and modular plugin system for my website. I need to be able to access plugin php files that exist in a plugin directory and get access to their classes to call functions such as getting the html content that the plugin should show and more.
Below is a semi-pseudo code example of what I am trying to achieve, but how to actually arbitrarily load the plugins is where I am stuck (PluginLoader.php).
-Max
//BasePlugin.php
abstract class BasePlugin
{
public function displayContent()
{
print "<p>Base Plugin</p>";
}
};
//ExamplePlugin.php -> In specific plugin directory.
require('../BasePlugin.php');
class ExamplePlugin extends BasePlugin
{
public static function Instance()
{
static $inst = null;
if ($inst === null) {
$inst = new ExamplePlugin();
}
return $inst;
}
public function displayContent()
{
print "<p>Example Plugin</p>";
}
}
//PluginLoader.php
foreach($pluginFile : PluginFilesInDirectory) { // Iterate over plugin php files in plugin directory
$plugin = GetPlugin($pluginFile); // Somehow get instance of plugin.
echo plugin->displayContent();
}
I'm guessing here, but it seems to me that you need to:
get a list of the plugins in the desired directory.
include or require the plugin's class file.
create an instance of the class.
call the plugin's displayContent() method.
So, you probably want to do something like
$pluginDir = 'your/plugin/directory/' ;
$plugins = glob($pluginDir . '*.php') ;
foreach($plugins as $plugin) {
// include the plugin file
include_once($plugin) ;
// grab the class name from the plugin's file name
// this finds the last occurrence of a '/' and gets the file name without the .php
$className = substr($plugin,strrpos($plugin,'/') + 1, -4) ;
// create the instance and display your test
$aPlugin = $className::Instance() ;
$aPlugin->displayContent() ;
}
There's probably a cleaner way to do it, but that will ready your directory, get the plugins' code, and instantiate each one. How you manage/reference them afterwards depends on how your plugins register with your application.

Magento2 - Newbie Select product

I have a site running Magento 2.2.1. I need to create a very simple PHP page that will look up a given product. I want to look up the product based on the SKU and just print the price and product URL out.
I have NO idea how to even start this. I have tried using this to test loading a product with ID = 1
//Get Object Manager Instance
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
//Load product by product id
$product = $objectManager->create('Magento\Catalog\Model\Product')->load(1);
but all that does is throw an exeception that ObjectManager is not found. So I tried including the /app/bootstrap.php file beforehand, and that throws an error that the ObjectManager isn't initialized.
Can anyone provide me with a simple example that I can drop into the root of my site that will allow me to look up a single product by sku? Or point me in the direction of some useful documentation?
The solution to load a product programmatically in simple PHP file by using ObjectManager, but this solution is not recommended by Magento 2.
<?php
include('app/bootstrap.php');
use Magento\Framework\App\Bootstrap;
$bootstrap = Bootstrap::create(BP, $_SERVER);
$objectManager = $bootstrap->getObjectManager();
$state = $objectManager->get('Magento\Framework\App\State');
$state->setAreaCode('frontend');
$productId = 1;
$product = $objectManager->create('Magento\Catalog\Model\Product')->load($productId);
echo $product->getName();
?>
Recommended Solution (Magento 2)
In Magento 2, the recommended way of loading product is by using ProductRepository and ProductFactory in a proper custom module instead of simple PHP file. Well, by using below (recommended) code, you can load product in your custom block.
ProductFactory Solution
<?php
namespace [Vendor_Name]\[Module_Name]\Block;
use Magento\Catalog\Model\ProductFactory;
class Product extends \Magento\Framework\View\Element\Template
{
protected $_productloader;
public function __construct(
ProductFactory $_productloader
) {
$this->_productloader = $_productloader;
}
public function getLoadProduct($id)
{
return $this->_productloader->create()->load($id);
}
}
In Magento 2.1
ProductRepository Solution
namespace [Vendor_Name]\[Module_Name]\Block;
use Magento\Catalog\Api\ProductRepositoryInterface;
class Product extends \Magento\Framework\View\Element\Template
{
protected $_productRepository;
public function __construct(
ProductRepositoryInterface $productRepository
) {
$this->_productRepository = $productRepository;
}
public function getProduct($id)
{
return $product = $this->productRepository->getById($id);
}
}
and, your .phtml file should look like this:
$productId = 1;
$product = $this->getLoadProduct($productId);
echo $product->getName();
I hope, you already know how to create a custom module in Magento 2 or if you want then just read this blog post How to create a basic module in Magento 2
You Cant just Load a Page By simple PHP file in magento Here is the procedure
1)create a layout file in you theme
2)register it inside layout.xml
3)add phtml to your layout file
4)add you code(in your question ) in that phtml file
the 2nd way is quite complecated
create module and in module controller render your code

php undefined variable error when calling class method

I have been writing procedural php for years and am very comfortable with it. Recently I decided to rework an existing site and switch to PDO and OOP. Everyone is telling me that this is a better way to go but the learning curve is killing me. When trying to call a class, I get the following.
Menu Builder
vbls: 5 1
Notice: Undefined variable: Menu in /home/lance/DallyPost/projectWebSite/trunk/1/core/modules/menuBuilder.php on line 9
Fatal error: Call to a member function menuFramework() on a non-object in /home/lance/DallyPost/projectWebSite/trunk/1/core/modules/menuBuilder.php on line 9
The procedure is that I have included menu.php at the top of index.php, prior to including the following script:
<?php
//menuBuilder.php
echo"<h2>$pageTitle</h2>";
$pub = $_URI_KEY['PUB'];
$dir = $_URI_KEY['DIRECTORY'];
echo"vbls: $pub $dir";
if($Menu->menuFramework("$pub", "$dir") === false) {
echo"The base menu framework failed to build correctly.";
}
else{
echo"<p>The base menu framework has been successfully constructed.</p>";
}
?>
As you can see, the above script calls a method in the Menu class:
<?php
//menu.php
class Menu{
private $db;
public function __construct($database) {
$this->db = $database;
}
public function menuFramework($pub, $directory){
$link = "/" . $directory . "/index.php/" . $pub . "/home/0/Home-Page/";
$inc = "core/menus/" . $pub . "category.php";
$file = "core/menus/" . $pub . "menuFramework.php";
$text = "<nav class=\"top-bar\" data-topbar>";
$text .= "<ul class=\"title-area\">";
$text .= "<li class=\"name\">";
$text .= "<h1>Home Page</h1>";
$text .= "</li>";
$text .= "</ul>";
$text .= "include($inc)";
$text .= "</nav>";
//write text to a file
if(file_put_contents($file, $text)){
return true;
}
else{
return false;
}
}
... rest of file not shown
Can you help me understand why I am getting this error. My understanding is that the variable was or should have been defined when I included menu.php, which was done before which was called a the top if index.php
Thanks
add this at the top of the script
$menu = new Menu($dbHandle);
That's not how classes work. You can't reference an entire class, Menu, with a variable, $Menu, to invoke instance methods.
You need to create an instance of your class on which to invoke methods:
$menu = new Menu(...);
You can create class-level "static" methods which are invoked on the class itself, but that syntax doesn't involve $Menu. You would use Menu::method_name() for that.
You are calling $Menu->
so your are a calling a variable called Menu, instead of the class Menu.
anyways, that function is not static, so you need to instantiate an object.
For that, add a this line:
$menu = new Menu($db);
where $db is your database object, if you really need it, or null if you dont (i cannot say with that code fragment)
and then call
$menu->menuFramework(...)

What is the right way to include plugins files in plugin system

I've created a plugins system, and I've created everything in that system except, how can I inclusion plugins files to execute it.
I'm tried to create a method, Which is doing include plugins files to execute it.
-- Firstly -- :
The method that get all plugins files, and that begin with index word which indicates the main file of plugin (i.g. index-pluginName.php), and add the path and file name to an array.
public function getPluginFiles($plugin_folder) {
$dir = opendir($plugin_folder);
while ($files = readdir($dir)) {
if ($files == '.' || $files == '..')
continue;
if (is_dir($plugin_folder.'/'.$files))
$this->getPluginFiles($plugin_folder.'/'.$files);
if (preg_match('/^[index]+/i', $files)) {
$this->plugins_path[$plugin_folder.'/'.$files] = $files;
}
}
closedir($dir);
}
-- secondly -- :
The method that include all the main file of plugins to execute, and this method get the path and name of plugin file from the array that created earlier .
public function includePlugFiles() {
$this->getPluginFiles($this->plugin_folder);
foreach ($this->plugins_path as $dir=>$file) {
include_once (dirname($dir)."/".$file);
}
}
Also see an example of code that exists in plugin file:
function test() {
echo " This is first plugin <br/>";
}
$plugin->addHook('top', test); // parameters(top=position, test=callback)
Now, when I create an instance of the object to be this form .
$plugin = new plugin;
$plugin->includePlugFiles();
But after all this, shows error message
Fatal error: Call to a member function addHook() on a non-object in .... projects\plugins\index-test.php on line 7
This is the code of line 7:
$plugin->addHook('top', test); // parameters(top=position, test=callback)
I know the problem occur because, the object will not be created.
and the problem is can't create the object in every main plugin file.
It's probably not the cleanest solution, but instead of trying to reference the $plugin symbol (which is outside the scope of the plugin file), you could also do this:
$this->addHook('top', test);
Alternatively, you could explicitly create the reference inside the includePlugFiles() method:
public function includePlugFiles()
{
$plugin = $this;
$this->getPluginFiles($this->plugin_folder);
foreach ($this->plugins_path as $dir=>$file) {
include_once (dirname($dir)."/".$file);
}
}

Categories