Magento2: Updating a line of code in core file - php

Here is what I need:
In file vendor/magento/module-sales-rule/Model/Rule/Action/Discount/CartFixed.php there is a public function calculate
I want to comment an If condition inside this function without modifying this core file.
if ($availableDiscountAmount > 0) {
I have created a preference inside a custom module but it is not working as expected. I really appreciate if anyone can help me on this.

To customize Magento core file, you can use Preference or Plugin. More detail here
In your case, you can use preference as the following steps:
In the di.xml you can add the reference config:
<preference for="Magento\SalesRule\Model\Rule\Action\Discount\CartFixed" type="Training\Test\Model\Rule\Action\Discount\CartFixed" />
Create Training\Test\Model\Rule\Action\Discount\CartFixed.php:
#author Bach Lee
*/
namespace Training\Test\Model\Rule\Action\Discount;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Pricing\PriceCurrencyInterface;
use Magento\SalesRule\Model\DeltaPriceRound;
use Magento\SalesRule\Model\Validator;
use Magento\SalesRule\Model\Rule\Action\DiscountFactory;
class CartFixed extends \Magento\SalesRule\Model\Rule\Action\Discount\CartFixed
{
/**
* #var string
*/
private static $discountType = 'CartFixed';
/**
* #var DeltaPriceRound
*/
private $deltaPriceRound;
/**
* #param Validator $validator
* #param DataFactory $discountDataFactory
* #param PriceCurrencyInterface $priceCurrency
* #param DeltaPriceRound $deltaPriceRound
*/
public function __construct(
Validator $validator,
DataFactory $discountDataFactory,
PriceCurrencyInterface $priceCurrency,
DeltaPriceRound $deltaPriceRound = null
) {
$this->deltaPriceRound = $deltaPriceRound ?: ObjectManager::getInstance()->get(DeltaPriceRound::class);
parent::__construct($validator, $discountDataFactory, $priceCurrency, $deltaPriceRound);
}
/**
* #param \Magento\SalesRule\Model\Rule $rule
* #param \Magento\Quote\Model\Quote\Item\AbstractItem $item
* #param float $qty
* #return \Magento\SalesRule\Model\Rule\Action\Discount\Data
* #throws \Magento\Framework\Exception\LocalizedException
*/
public function calculate($rule, $item, $qty)
{
/** #var \Magento\SalesRule\Model\Rule\Action\Discount\Data $discountData */
$discountData = $this->discountFactory->create();
$ruleTotals = $this->validator->getRuleItemTotalsInfo($rule->getId());
$quote = $item->getQuote();
$address = $item->getAddress();
$itemPrice = $this->validator->getItemPrice($item);
$baseItemPrice = $this->validator->getItemBasePrice($item);
$itemOriginalPrice = $this->validator->getItemOriginalPrice($item);
$baseItemOriginalPrice = $this->validator->getItemBaseOriginalPrice($item);
/**
* prevent applying whole cart discount for every shipping order, but only for first order
*/
if ($quote->getIsMultiShipping()) {
$usedForAddressId = $this->getCartFixedRuleUsedForAddress($rule->getId());
if ($usedForAddressId && $usedForAddressId != $address->getId()) {
return $discountData;
} else {
$this->setCartFixedRuleUsedForAddress($rule->getId(), $address->getId());
}
}
$cartRules = $address->getCartFixedRules();
if (!isset($cartRules[$rule->getId()])) {
$cartRules[$rule->getId()] = $rule->getDiscountAmount();
}
$availableDiscountAmount = (float)$cartRules[$rule->getId()];
$discountType = self::$discountType . $rule->getId();
$store = $quote->getStore();
if ($ruleTotals['items_count'] <= 1) {
$quoteAmount = $this->priceCurrency->convert($availableDiscountAmount, $store);
$baseDiscountAmount = min($baseItemPrice * $qty, $availableDiscountAmount);
$this->deltaPriceRound->reset($discountType);
} else {
$ratio = $baseItemPrice * $qty / $ruleTotals['base_items_price'];
$maximumItemDiscount = $this->deltaPriceRound->round(
$rule->getDiscountAmount() * $ratio,
$discountType
);
$quoteAmount = $this->priceCurrency->convert($maximumItemDiscount, $store);
$baseDiscountAmount = min($baseItemPrice * $qty, $maximumItemDiscount);
$this->validator->decrementRuleItemTotalsCount($rule->getId());
}
$baseDiscountAmount = $this->priceCurrency->round($baseDiscountAmount);
$availableDiscountAmount -= $baseDiscountAmount;
$cartRules[$rule->getId()] = $availableDiscountAmount;
if ($availableDiscountAmount <= 0) {
$this->deltaPriceRound->reset($discountType);
}
$discountData->setAmount($this->priceCurrency->round(min($itemPrice * $qty, $quoteAmount)));
$discountData->setBaseAmount($baseDiscountAmount);
$discountData->setOriginalAmount(min($itemOriginalPrice * $qty, $quoteAmount));
$discountData->setBaseOriginalAmount($this->priceCurrency->round($baseItemOriginalPrice));
$address->setCartFixedRules($cartRules);
return $discountData;
}
}
Or you can use cweagans/composer-patches following this question to edit core Magento files
Regards

Use like this
code/Magento/* any name or module you need from core file
If you need some more details let me know it is just like Magento 1 but only folder is changed

App/Code/Magento/SalesRule/model/ *
Please use it like this

After adding this please use compile command

It works for me it will work for you also
First add folders
App/Code/Magento/SalesRule/model/folder/file.php
And thank use "setup:upgrade" to update the files.
Than command "setup:di:compile".
Regards
Naseem

Related

How to get image of different repository? [Typo3]

I already had a question regarding "importing" records and there data of different plugins/extensions. I got it working after adding the pid and implemented a query builder to get the data of a different plugin (or table in this case). But now I got the problem that the images of the "foreign" table/records or whatever is not included.. when I debug the var the image is only set to int 1. But they are not correctly included. What do I need to do to get this s*** working? :)
//MY CONTROLLER
<?php
namespace Formschoen\Mitarbeiterajax\Controller;
use TYPO3\CMS\Core\Context\Context;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* MitarbeiterController
*/
class MitarbeiterController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController
{
/**
* mitarbeiterRepository
*
* #var \Formschoen\Mitarbeiterajax\Domain\Repository\MitarbeiterRepository
*/
protected $mitarbeiterRepository = null;
/**
* #param \Formschoen\Mitarbeiterajax\Domain\Repository\MitarbeiterRepository $mitarbeiterRepository
*/
public function injectMitarbeiterRepository(\Formschoen\Mitarbeiterajax\Domain\Repository\MitarbeiterRepository $mitarbeiterRepository)
{
$this->mitarbeiterRepository = $mitarbeiterRepository;
}
/**
* optionRecordRepository
*
* #var \Sebkln\Ajaxselectlist\Domain\Repository\OptionRecordRepository
*/
protected $optionRecordRepository;
/**
* #param \Sebkln\Ajaxselectlist\Domain\Repository\OptionRecordRepository
*/
public function injectOptionRecordRepository(\Sebkln\Ajaxselectlist\Domain\Repository\OptionRecordRepository $optionRecordRepository) {
$this->optionRecordRepository = $optionRecordRepository;
}
/**
* action list
*
* #return void
*/
public function listAction()
{
$mitarbeiters = $this->mitarbeiterRepository->findAll();
$this->view->assign('mitarbeiters', $mitarbeiters);
$this->view->assign("currentPageID", $GLOBALS['TSFE']->id);
$options['autohaus'] = array(
1 => 'some strings'
);
$options['abteilung'] = array(
1 => 'some strings'
);
$this->view->assign('options', $options);
}
/**
* action callAjax
*
* #param \Formschoen\Mitarbeiterajax\Domain\Model\Mitarbeiter $mitarbeiter
* #return void
*/
public function callAjaxAction(\Formschoen\Mitarbeiterajax\Domain\Model\Mitarbeiter $mitarbeiter)
{
$optionRecords = $this->optionRecordRepository->findAll();
$arguments = $this->request->getArguments();
$selectedAutohaus = $arguments['autohaus'];
$selectedAbteilung = $arguments['abteilung'];
if ($selectedAbteilung == null && $selectedAutohaus == null) {
echo("Bitte ein Autohaus auswählen / eine Abteilung.");
} else if ($selectedAbteilung == null) {
$autohausResult = $this->mitarbeiterRepository->findAutohaus($selectedAutohaus);
$this->view->assign('autohausResult', $autohausResult);
} else {
$mitarbeiterResult = $this->mitarbeiterRepository->findByFilter($selectedAutohaus, $selectedAbteilung);
$this->view->assign('mitarbeiterResult', $mitarbeiterResult);
}
$this->contentObj = $this->configurationManager->getContentObject();
$images=$this->getFileReferences($this->contentObj->data['uid']);
$this->view->assign('images', $images);
}
}
//MY REPOSITORY
<?php
namespace Formschoen\Mitarbeiterajax\Domain\Repository;
/**
* The repository for Mitarbeiters
*/
class MitarbeiterRepository extends \TYPO3\CMS\Extbase\Persistence\Repository
{
/**
* #param $selectedAutohaus
* #param $selectedAbteilung
*/
public function findByFilter($selectedAutohaus,$selectedAbteilung){
$query = $this->createQuery();
$result = $query->matching($query->logicalAnd(
$query->equals('autohausName', $selectedAutohaus),
$query->equals('abteilung', $selectedAbteilung)
))
->execute();
return $result;
}
/**
* #param $uid
*/
public function findAutohaus($uid)
{
$queryBuilder = $this->objectManager->get(\TYPO3\CMS\Core\Database\ConnectionPool::class)
->getConnectionForTable('tx_ajaxselectlist_domain_model_optionrecord')->createQueryBuilder();
$queryBuilder
->select('*')
->from('tx_ajaxselectlist_domain_model_optionrecord')
->where(
$queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($uid))
);
$result = $queryBuilder->execute()->fetchAll();
if ($returnRawQueryResult) {
$dataMapper = $this->objectManager->get(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper::class);
return $dataMapper->map($this->objectType, $result);
}
return $result;
}
}
Why dont you just replace this
$autohausResult = $this->mitarbeiterRepository->findAutohaus($selectedAutohaus);
with this
$autohausResult = $this->optionRecordRepository->findByUid($selectedAutohaus);
This way TYPO3 will construct the Models and you will get the image they way you want it

Custom shipping method error: Please specify a shipping method

I have a variety of custom shipping methods in my store, but I noticed that, if the user is logged in, the order cannot be finished. The user chooses which shipping method they want and then they cannot pass the payment method, because it keeps giving this error: Please specify a shipping method.
Here's my code:
Model/Carrier/CustomShipping.php
<?php
namespace Magenticians\Moduleshipping\Model\Carrier;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\DataObject;
use Magento\Shipping\Model\Carrier\AbstractCarrier;
use Magento\Shipping\Model\Carrier\CarrierInterface;
use Magento\Shipping\Model\Config;
use Magento\Shipping\Model\Rate\ResultFactory;
use Magento\Store\Model\ScopeInterface;
use Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory;
use Magento\Quote\Model\Quote\Address\RateResult\Method;
use Magento\Quote\Model\Quote\Address\RateResult\MethodFactory;
use Magento\Quote\Model\Quote\Address\RateRequest;
use Psr\Log\LoggerInterface;
class Customshipping extends AbstractCarrier implements CarrierInterface
{
/**
* Carrier's code
*
* #var string
*/
protected $_code = 'magenticians_moduleshipping';
/**
* Whether this carrier has fixed rates calculation
*
* #var bool
*/
protected $_isFixed = true;
/**
* #var ResultFactory
*/
protected $_rateResultFactory;
/**
* #var MethodFactory
*/
protected $_rateMethodFactory;
/**
* #param ScopeConfigInterface $scopeConfig
* #param ErrorFactory $rateErrorFactory
* #param LoggerInterface $logger
* #param ResultFactory $rateResultFactory
* #param MethodFactory $rateMethodFactory
* #param array $data
*/
public function __construct(
ScopeConfigInterface $scopeConfig,
ErrorFactory $rateErrorFactory,
LoggerInterface $logger,
ResultFactory $rateResultFactory,
MethodFactory $rateMethodFactory,
array $data = []
) {
$this->_rateResultFactory = $rateResultFactory;
$this->_rateMethodFactory = $rateMethodFactory;
parent::__construct($scopeConfig, $rateErrorFactory, $logger, $data);
}
/**
* Generates list of allowed carrier's shipping methods
* Displays on cart price rules page
*
* #return array
* #api
*/
public function getAllowedMethods()
{
return [$this->getCarrierCode() => __($this->getConfigData('name'))];
}
/**
* Collect and get rates for storefront
*
* #SuppressWarnings(PHPMD.UnusedFormalParameter)
* #param RateRequest $request
* #return DataObject|bool|null
* #api
*/
public function collectRates(RateRequest $request)
{
/**
* Make sure that Shipping method is enabled
*/
if (!$this->isActive()) {
return false;
}
$weight = 0;
if ($request->getAllItems())
{
foreach ($request->getAllItems() as $item)
{
if ($item->getProduct()->isVirtual())
{
continue;
}
if ($item->getHasChildren())
{
foreach ($item->getChildren() as $child)
{
if (! $child->getProduct()->isVirtual())
{
$weight += $child->getWeight();
}
}
} else
{
$weight += $item->getWeight();
}
}
}
$final_weight = $weight;
/** #var \Magento\Shipping\Model\Rate\Result $result */
$result = $this->_rateResultFactory->create();
$shippingPrice = $this->getConfigData('price');
$method = $this->_rateMethodFactory->create();
/**
* Set carrier's method data
*/
$method->setCarrier($this->getCarrierCode());
$method->setCarrierTitle($this->getConfigData('title'));
/**
* Displayed as shipping method under Carrier
*/
$method->setMethod($this->getCarrierCode());
$method->setMethodTitle($this->getConfigData('name'));
$method->setPrice($shippingPrice);
$method->setCost($shippingPrice);
if($final_weight <= 2) {
$result->append($method);
}
return $result;
}
}
Can't seem to find a reason why, I compared my code with others and they look pretty much identical.
Thanks in advance.
Seems magento 2.2 is not loving underscore on attribute $_code.
$_code = 'magenticians_moduleshipping';
Try change to
protected $_code = 'magenticiansmoduleshipping';

CodeIgniter Models vs Symfony/Doctrine Models

Background:
I have build my web application using CodeIgniter because it was the only framework I could grasp easily enough to get going quickly. Now seeing the unbelievably advanced functionality of symfony and the PSR standards I am hyped to get into it all.
Dialemma
I am not sure how to approach the model layer with symfony/doctrine. As I understand it: doctrine generates an entity class for a database table like so...
This class contains a bunch of setter/getter functions.
My mental block at the moment is that I don't understand how I am supposed to add to functionality to my model layer.
To understand where I am coming from take a look at a typical CodeIgniter Model that I am currently working with. This one handles discount coupons.
<?php
/**
* This class handles all coupon codes
*/
class Coupon_Model extends CI_Model
{
/**
* gets a specific coupon
* #param string $coupon_code
* #return obj
*/
public function getCoupon($coupon_code)
{
$this->db->where('coupon_code', $coupon_code);
$query = $this->db->get('coupons');
return $query->row();
}
/**
* gets all coupons associated with a course
* #param int $course_id
* #return array
*/
public function getCourseCoupons($course_id)
{
$this->db->where('course_id', $course_id);
$query = $this->db->get('coupons');
return $query->result();
}
/**
* generates a string of 10 random alphanumeric numbers
* #return string
*/
public function generateCouponCode()
{
return strtoupper(substr(base_convert(sha1(uniqid(mt_rand())), 16, 36), 0, 10));
}
/**
* creates a new active coupon
* #param array $data
* #param string $coupon_code
* #return bool
*/
public function createCoupon($data, $coupon_code = null)
{
if ($coupon_code !== '') {
$data['coupon_code'] = $coupon_code;
} else {
$data['coupon_code'] = $this->generateCouponCode();
}
return $this->db->insert('coupons', $data);
}
/**
* checks if a coupon is valid
* #param string $coupon_code
* #param int $course_id
* #return bool
*/
public function checkCoupon($coupon_code, $course_id = null)
{
$this->db->where('coupon_code', $coupon_code);
$query = $this->db->get('coupons');
$coupon = $query->row();
// if coupon code exists
if ($coupon === null) {
return false;
}
// if coupon is for the right course
if ($coupon->course_id !== $course_id && $course_id !== null) {
return false;
}
// if coupon code has not expired
if ($coupon->expiry_date <= $this->Time_Model->getCarbonNow()->timestamp) {
return false;
}
return true;
}
/**
* deletes a coupon record
* #param int coupon_id
* #return bool
*/
public function deleteCoupon($coupon_id)
{
$this->db->where('coupon_id', $coupon_id);
return $this->db->delete('coupons');
}
/**
* applys the coupon discount
* #param int $price
* #param float $discount (percentage)
*/
public function applyDiscount($price, $discount)
{
$price = $price - (($discount / 100) * $price);
return $price;
}
}
As you can see it is pretty straight forward, if I wanted to add functionality I would literally just create a new function.
To use this model I would simply load it on the Controller like this:
$this->model->load('coupons/Coupon_Model');
$this->Coupon_Model->getCoupon($coupon_code);
Simple, done and dusted... unfortunately I am not sure how to implement this sort of functionality with symfony/doctrine.
Will I need to create a new class separate from the entity and add extra functionality to this class? Or should I add more functions to the entity class?
Take for example my simple function which generates the coupon code:
/**
* generates a string of 10 random alphanumeric numbers
* #return string
*/
public function generateCouponCode()
{
return strtoupper(substr(base_convert(sha1(uniqid(mt_rand())), 16, 36), 0, 10));
}
Where would be the best place to put this function? Under AppBundle/models/coupons?
I have clearly picked up bad habits from CodeIgniter and have a feeling that I am approaching this the wrong way.
Symfony + Doctrine ORM comes with a lot of the default needs for the replacement of CodeIgniter models by using the EntityManager within your Controller(s).
For example
namespace AppBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
class DefaultController extends Controller
{
/**
* #Route("/{id}/show", name="app_show", defaults={"id" = 1})
*/
public function showAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
if (!$coupon = $em->find('AppBundle:Coupon', $id)) {
throw new NotFoundException('Unknown Coupon Specified');
}
//see below to see how this was implemented
$similarCoupons = $em->getRepository('AppBundle:Coupon')
->filterCourse($coupon->course);
return $this->render('AppBundle:template.twig', [
'coupon' => $coupon,
'similarCoupons' => $similarCoupons
]);
}
/**
* #Route("/new", name="app_new")
*/
public function newAction(Request $request)
{
//use Symfony Form Component instead
$em = $this->getDoctrine()->getManager();
$coupon = new \AppBundle\Entity\Coupon;
//calls __construct to call generateCouponCode
$coupon->setName($request->get('name'));
$em->persist($coupon);
$em->flush();
return $this->redirectToRoute('app_show', ['id' => $coupon->getId()]);
}
//...
}
You want to specify the functionality you want each entity to have when working with it from within the Entity class.
That it becomes available without needing to revisit the repository, since an Entity should never be aware of the EntityManager.
In effect, each Entity can be considered their own models.
For example $coupon->generateCouponCode(); or $this->generateCouponCode() from within the entity.
Otherwise you would use a Repository of your Doctrine Database Entity(ies) to add more complex functionality.
// /src/AppBundle/Entity/Coupon.php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repository="CouponRepository")
*/
class Coupon
{
/**
* #var integer
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string
* #ORM\Column(name="name", type="string", length=50)
*/
private $name;
/**
* #var string
* #ORM\Column(name="coupon_code", type="string", length=10)
*/
private $couponCode;
/**
* #var Course
* #ORM\ManyToOne(targetEntity="Course", inversedBy="coupons")
* #ORM\JoinColumn(name="course", referencedColumnName="id")
*/
private $course;
//...
public function __construct()
{
//optionally create code when persisting a new database entry by using LifeCycleCallbacks or a Listener instead of this line.
$this->couponCode = $this->generateCouponCode();
}
//...
/**
* generates a string of 10 random alphanumeric numbers
* #return string
*/
public function generateCouponCode()
{
return strtoupper(substr(base_convert(sha1(uniqid(mt_rand())), 16, 36), 0, 10));
}
}
Then your custom queries would go into your Repository.
// /src/AppBundle/Entity/CouponRepository.php
namespace AppBundle\Entity;
use Doctrine\ORM\EntityRepository;
class CouponRepository extends EntityRepository
{
/**
* filters a collection of Coupons that matches the supplied Course
* #param Course $course
* #return array|Coupons[]
*/
public function filterCourse(Course $course)
{
$qb = $this->createQueryBuilder('c');
$expr = $qb->expr();
$qb->where($expr->eq('c.course', ':course'))
->setParameter('course', $course);
return $qb->getQuery()->getResult();
}
}
Additionally you can filter collections of an association (Foreign Key) reference within your entity.
namespace AppBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Criteria;
//...
class Course
{
//...
/**
* #var ArrayCollection|Coupon[]
* #ORM\OneToMany(targetEntity="Coupon", mappedBy="course")
*/
private $coupons;
public function __construct()
{
$this->coupons = new ArrayCollection;
}
/**
* #return ArrayCollection|Coupon[]
*/
public function getCoupons()
{
return $this->coupons;
}
/**
* #param string $name
* #return \Doctrine\Common\Collections\Collection|Coupon[]
*/
public function getCouponsByName($name)
{
$criteria = Criteria::create();
$expr = $criteria::expr();
return $this->coupons->matching($criteria->where($expr->eq('name', $name)));
}
}

TYPO3 - 7.2 FLUID Error: file_get_contents() Filename empty

I set up an local TYPO3 7.2 environment with xampp.
The installation works fine and everything else too.
At the beginning I installed the FluidTYPO3 site kickstarter distribution because I wanted to work with FLUID there. The distribution created all extensions needed for that (vhs, flux, fluidpages, fluidcontent) and then I created my provider extension with the builder.
It also created 4 pages or 1 page and 3 subpages. As I wanted to rename them I got the following error/exception:
PHP Warning: file_get_contents(): Filename cannot be empty in F:\xampp\htdocs\src\typo3_src-7.2.0\typo3\sysext\fluid\Classes\View\TemplateView.php line 318
I tried to var_dump() that in that file but it didn't help. I get the correct path and filename on other modules but not on the "page"-module where the error appeared. I can not rename, delete or edit the pages.
It seems that something is null there, mh.
Later I saw that the extensions were not for my TYPO3 version 7.2, only for 6.2.99 I think. So I deinstalled all extensions and downloaded the development extensions from Github (https://github.com/FluidTYPO3).
I installed them with an error that my version is too high. The extensions are only for 7.1.99. I thought that it would not be a problem and it should work with it anyway.
As I tested it there was the same error again, again and again.
I don't know where the problem is. Everything works fine on 6.x installations.
Could that be a bug or did I forget something?
PHP Version: 5.6.3 /
TYPO3 Version: 7.2
Would be very nice if anyone knows about the problem or could help me to solve it. I don't know which information is needed. Feel free to ask if something is needed.
<?php
namespace TYPO3\CMS\Fluid\View;
/* *
* This script is backported from the TYPO3 Flow package "TYPO3.Fluid". *
* *
* It is free software; you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License, either version 3 *
* of the License, or (at your option) any later version. *
* *
* The TYPO3 project - inspiring people to share! *
* */
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext;
use TYPO3\CMS\Extbase\Object\ObjectManager;
use TYPO3\CMS\Fluid\Compatibility\TemplateParserBuilder;
use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextInterface;
use TYPO3\CMS\Fluid\Fluid;
/**
* The main template view. Should be used as view if you want Fluid Templating
*
* #api
*/
class TemplateView extends AbstractTemplateView {
/**
* Pattern to be resolved for "#templateRoot" in the other patterns.
* Following placeholders are supported:
* - "#packageResourcesPath"
*
* #var string
*/
protected $templateRootPathPattern = '#packageResourcesPath/Private/Templates';
/**
* Pattern to be resolved for "#partialRoot" in the other patterns.
* Following placeholders are supported:
* - "#packageResourcesPath"
*
* #var string
*/
protected $partialRootPathPattern = '#packageResourcesPath/Private/Partials';
/**
* Pattern to be resolved for "#layoutRoot" in the other patterns.
* Following placeholders are supported:
* - "#packageResourcesPath"
*
* #var string
*/
protected $layoutRootPathPattern = '#packageResourcesPath/Private/Layouts';
/**
* Path(s) to the template root. If NULL, then $this->templateRootPathPattern will be used.
*
* #var array
*/
protected $templateRootPaths = NULL;
/**
* Path(s) to the partial root. If NULL, then $this->partialRootPathPattern will be used.
*
* #var array
*/
protected $partialRootPaths = NULL;
/**
* Path(s) to the layout root. If NULL, then $this->layoutRootPathPattern will be used.
*
* #var array
*/
protected $layoutRootPaths = NULL;
/**
* File pattern for resolving the template file
* Following placeholders are supported:
* - "#templateRoot"
* - "#partialRoot"
* - "#layoutRoot"
* - "#subpackage"
* - "#action"
* - "#format"
*
* #var string
*/
protected $templatePathAndFilenamePattern = '#templateRoot/#subpackage/#controller/#action.#format';
/**
* Directory pattern for global partials. Not part of the public API, should not be changed for now.
* Following placeholders are supported:
* - "#templateRoot"
* - "#partialRoot"
* - "#layoutRoot"
* - "#subpackage"
* - "#partial"
* - "#format"
*
* #var string
*/
private $partialPathAndFilenamePattern = '#partialRoot/#subpackage/#partial.#format';
/**
* File pattern for resolving the layout
* Following placeholders are supported:
* - "#templateRoot"
* - "#partialRoot"
* - "#layoutRoot"
* - "#subpackage"
* - "#layout"
* - "#format"
*
* #var string
*/
protected $layoutPathAndFilenamePattern = '#layoutRoot/#layout.#format';
/**
* Path and filename of the template file. If set, overrides the templatePathAndFilenamePattern
*
* #var string
*/
protected $templatePathAndFilename = NULL;
/**
* Path and filename of the layout file. If set, overrides the layoutPathAndFilenamePattern
*
* #var string
*/
protected $layoutPathAndFilename = NULL;
/**
* Constructor
*/
public function __construct() {
$this->templateParser = TemplateParserBuilder::build();
$this->objectManager = GeneralUtility::makeInstance(ObjectManager::class);
$this->setRenderingContext($this->objectManager->get(RenderingContextInterface::class));
}
/**
* Init view
*/
public function initializeView() {
}
// Here, the backporter can insert a constructor method, which is needed for the TYPO3 CMS extension
/**
* Sets the path and name of of the template file. Effectively overrides the
* dynamic resolving of a template file.
*
* #param string $templatePathAndFilename Template file path
* #return void
* #api
*/
public function setTemplatePathAndFilename($templatePathAndFilename) {
$this->templatePathAndFilename = $templatePathAndFilename;
}
/**
* Sets the path and name of the layout file. Overrides the dynamic resolving of the layout file.
*
* #param string $layoutPathAndFilename Path and filename of the layout file
* #return void
* #api
*/
public function setLayoutPathAndFilename($layoutPathAndFilename) {
$this->layoutPathAndFilename = $layoutPathAndFilename;
}
/**
* Set the root path to the templates.
* If set, overrides the one determined from $this->templateRootPathPattern
*
* #param string $templateRootPath Root path to the templates. If set, overrides the one determined from $this->templateRootPathPattern
* #return void
* #api
* #see setTemplateRootPaths()
*/
public function setTemplateRootPath($templateRootPath) {
$this->setTemplateRootPaths(array($templateRootPath));
}
/**
* Resolves the template root to be used inside other paths.
*
* #return array Path(s) to template root directory
*/
public function getTemplateRootPaths() {
if ($this->templateRootPaths !== NULL) {
return $this->templateRootPaths;
}
/** #var $actionRequest \TYPO3\CMS\Extbase\Mvc\Request */
$actionRequest = $this->controllerContext->getRequest();
return array(str_replace('#packageResourcesPath', ExtensionManagementUtility::extPath($actionRequest->getControllerExtensionKey()) . 'Resources/', $this->templateRootPathPattern));
}
/**
* Set the root path(s) to the templates.
* If set, overrides the one determined from $this->templateRootPathPattern
*
* #param array $templateRootPaths Root path(s) to the templates. If set, overrides the one determined from $this->templateRootPathPattern
* #return void
* #api
*/
public function setTemplateRootPaths(array $templateRootPaths) {
$this->templateRootPaths = $templateRootPaths;
}
/**
* Set the root path to the partials.
* If set, overrides the one determined from $this->partialRootPathPattern
*
* #param string $partialRootPath Root path to the partials. If set, overrides the one determined from $this->partialRootPathPattern
* #return void
* #api
* #see setPartialRootPaths()
*/
public function setPartialRootPath($partialRootPath) {
$this->setPartialRootPaths(array($partialRootPath));
}
/**
* Set the root path(s) to the partials.
* If set, overrides the one determined from $this->partialRootPathPattern
*
* #param array $partialRootPaths Root paths to the partials. If set, overrides the one determined from $this->partialRootPathPattern
* #return void
* #api
*/
public function setPartialRootPaths(array $partialRootPaths) {
$this->partialRootPaths = $partialRootPaths;
}
/**
* Resolves the partial root to be used inside other paths.
*
* #return array Path(s) to partial root directory
*/
protected function getPartialRootPaths() {
if ($this->partialRootPaths !== NULL) {
return $this->partialRootPaths;
}
/** #var $actionRequest \TYPO3\CMS\Extbase\Mvc\Request */
$actionRequest = $this->controllerContext->getRequest();
return array(str_replace('#packageResourcesPath', ExtensionManagementUtility::extPath($actionRequest->getControllerExtensionKey()) . 'Resources/', $this->partialRootPathPattern));
}
/**
* Set the root path to the layouts.
* If set, overrides the one determined from $this->layoutRootPathPattern
*
* #param string $layoutRootPath Root path to the layouts. If set, overrides the one determined from $this->layoutRootPathPattern
* #return void
* #api
* #see setLayoutRootPaths()
*/
public function setLayoutRootPath($layoutRootPath) {
$this->setLayoutRootPaths(array($layoutRootPath));
}
/**
* Set the root path(s) to the layouts.
* If set, overrides the one determined from $this->layoutRootPathPattern
*
* #param array $layoutRootPaths Root path to the layouts. If set, overrides the one determined from $this->layoutRootPathPattern
* #return void
* #api
*/
public function setLayoutRootPaths(array $layoutRootPaths) {
$this->layoutRootPaths = $layoutRootPaths;
}
/**
* Resolves the layout root to be used inside other paths.
*
* #return string Path(s) to layout root directory
*/
protected function getLayoutRootPaths() {
if ($this->layoutRootPaths !== NULL) {
return $this->layoutRootPaths;
}
/** #var $actionRequest \TYPO3\CMS\Extbase\Mvc\Request */
$actionRequest = $this->controllerContext->getRequest();
return array(str_replace('#packageResourcesPath', ExtensionManagementUtility::extPath($actionRequest->getControllerExtensionKey()) . 'Resources/', $this->layoutRootPathPattern));
}
/**
* Returns a unique identifier for the resolved template file
* This identifier is based on the template path and last modification date
*
* #param string $actionName Name of the action. If NULL, will be taken from request.
* #return string template identifier
*/
protected function getTemplateIdentifier($actionName = NULL) {
$templatePathAndFilename = $this->getTemplatePathAndFilename($actionName);
if ($actionName === NULL) {
/** #var $actionRequest \TYPO3\CMS\Extbase\Mvc\Request */
$actionRequest = $this->controllerContext->getRequest();
$actionName = $actionRequest->getControllerActionName();
}
$prefix = 'action_' . $actionName;
return $this->createIdentifierForFile($templatePathAndFilename, $prefix);
}
/**
* Resolve the template path and filename for the given action. If $actionName
* is NULL, looks into the current request.
*
* #param string $actionName Name of the action. If NULL, will be taken from request.
* #return string Full path to template
* #throws Exception\InvalidTemplateResourceException
*/
protected function getTemplateSource($actionName = NULL) {
$templatePathAndFilename = $this->getTemplatePathAndFilename($actionName);
$templateSource = file_get_contents($templatePathAndFilename);
if ($templateSource === FALSE) {
throw new Exception\InvalidTemplateResourceException('"' . $templatePathAndFilename . '" is not a valid template resource URI.', 1257246929);
}
return $templateSource;
}
/**
* Resolve the template path and filename for the given action. If $actionName
* is NULL, looks into the current request.
*
* #param string $actionName Name of the action. If NULL, will be taken from request.
* #return string Full path to template
* #throws Exception\InvalidTemplateResourceException
*/
protected function getTemplatePathAndFilename($actionName = NULL) {
if ($this->templatePathAndFilename !== NULL) {
return $this->resolveFileNamePath($this->templatePathAndFilename);
}
if ($actionName === NULL) {
/* #var $actionRequest \TYPO3\CMS\Extbase\Mvc\Request */
$actionRequest = $this->controllerContext->getRequest();
$actionName = $actionRequest->getControllerActionName();
}
$paths = $this->expandGenericPathPattern($this->templatePathAndFilenamePattern, FALSE, FALSE);
$possibleFileNames = $this->buildListOfTemplateCandidates($actionName, $paths, '#action');
foreach ($possibleFileNames as $templatePathAndFilename) {
if ($this->testFileExistence($templatePathAndFilename)) {
return $templatePathAndFilename;
}
}
throw new Exception\InvalidTemplateResourceException('Template could not be loaded. I tried "' . implode('", "', $possibleFileNames) . '"', 1225709595);
}
/**
* Returns a unique identifier for the resolved layout file.
* This identifier is based on the template path and last modification date
*
* #param string $layoutName The name of the layout
* #return string layout identifier
*/
protected function getLayoutIdentifier($layoutName = 'Default') {
$layoutPathAndFilename = $this->getLayoutPathAndFilename($layoutName);
$prefix = 'layout_' . $layoutName;
return $this->createIdentifierForFile($layoutPathAndFilename, $prefix);
}
/**
* Resolve the path and file name of the layout file, based on
* $this->layoutPathAndFilename and $this->layoutPathAndFilenamePattern.
*
* In case a layout has already been set with setLayoutPathAndFilename(),
* this method returns that path, otherwise a path and filename will be
* resolved using the layoutPathAndFilenamePattern.
*
* #param string $layoutName Name of the layout to use. If none given, use "Default"
* #return string contents of the layout template
* #throws Exception\InvalidTemplateResourceException
*/
protected function getLayoutSource($layoutName = 'Default') {
$layoutPathAndFilename = $this->getLayoutPathAndFilename($layoutName);
$layoutSource = file_get_contents($layoutPathAndFilename);
if ($layoutSource === FALSE) {
throw new Exception\InvalidTemplateResourceException('"' . $layoutPathAndFilename . '" is not a valid template resource URI.', 1257246930);
}
return $layoutSource;
}
/**
* Resolve the path and file name of the layout file, based on
* $this->layoutPathAndFilename and $this->layoutPathAndFilenamePattern.
*
* In case a layout has already been set with setLayoutPathAndFilename(),
* this method returns that path, otherwise a path and filename will be
* resolved using the layoutPathAndFilenamePattern.
*
* #param string $layoutName Name of the layout to use. If none given, use "Default"
* #return string Path and filename of layout files
* #throws Exception\InvalidTemplateResourceException
*/
protected function getLayoutPathAndFilename($layoutName = 'Default') {
if ($this->layoutPathAndFilename !== NULL) {
return $this->resolveFileNamePath($this->layoutPathAndFilename);
}
$paths = $this->expandGenericPathPattern($this->layoutPathAndFilenamePattern, TRUE, TRUE);
$possibleFileNames = $this->buildListOfTemplateCandidates($layoutName, $paths, '#layout');
foreach ($possibleFileNames as $layoutPathAndFilename) {
if ($this->testFileExistence($layoutPathAndFilename)) {
return $layoutPathAndFilename;
}
}
throw new Exception\InvalidTemplateResourceException('The layout files "' . implode('", "', $possibleFileNames) . '" could not be loaded.', 1225709596);
}
/**
* Returns a unique identifier for the resolved partial file.
* This identifier is based on the template path and last modification date
*
* #param string $partialName The name of the partial
* #return string partial identifier
*/
protected function getPartialIdentifier($partialName) {
$partialPathAndFilename = $this->getPartialPathAndFilename($partialName);
$prefix = 'partial_' . $partialName;
return $this->createIdentifierForFile($partialPathAndFilename, $prefix);
}
/**
* Figures out which partial to use.
*
* #param string $partialName The name of the partial
* #return string contents of the partial template
* #throws Exception\InvalidTemplateResourceException
*/
protected function getPartialSource($partialName) {
$partialPathAndFilename = $this->getPartialPathAndFilename($partialName);
$partialSource = file_get_contents($partialPathAndFilename);
if ($partialSource === FALSE) {
throw new Exception\InvalidTemplateResourceException('"' . $partialPathAndFilename . '" is not a valid template resource URI.', 1257246931);
}
return $partialSource;
}
/**
* Resolve the partial path and filename based on $this->partialPathAndFilenamePattern.
*
* #param string $partialName The name of the partial
* #return string the full path which should be used. The path definitely exists.
* #throws Exception\InvalidTemplateResourceException
*/
protected function getPartialPathAndFilename($partialName) {
$paths = $this->expandGenericPathPattern($this->partialPathAndFilenamePattern, TRUE, TRUE);
$possibleFileNames = $this->buildListOfTemplateCandidates($partialName, $paths, '#partial');
foreach ($possibleFileNames as $partialPathAndFilename) {
if ($this->testFileExistence($partialPathAndFilename)) {
return $partialPathAndFilename;
}
}
throw new Exception\InvalidTemplateResourceException('The partial files "' . implode('", "', $possibleFileNames) . '" could not be loaded.', 1225709597);
}
/**
* Builds a list of possible candidates for a given template name
*
* #param string $templateName
* #param array $paths Paths to search in
* #param string $marker Marker to replace in the $templateName
* #return array Array of paths to search for the template file
*/
protected function buildListOfTemplateCandidates($templateName, $paths, $marker) {
$upperCasedTemplateName = $this->ucFileNameInPath($templateName);
$possibleFileNames = array();
foreach ($paths as $partialPathAndFilename) {
$possibleFileNames[] = $this->resolveFileNamePath(str_replace($marker, $upperCasedTemplateName, $partialPathAndFilename));
if ($templateName !== $upperCasedTemplateName) {
$possibleFileNames[] = $this->resolveFileNamePath(str_replace($marker, $templateName, $partialPathAndFilename));
}
}
return $possibleFileNames;
}
/**
* Checks whether a template can be resolved for the current request context.
*
* #param ControllerContext $controllerContext Controller context which is available inside the view
* #return bool
* #api
*/
public function canRender(ControllerContext $controllerContext) {
$this->setControllerContext($controllerContext);
try {
$this->getTemplateSource();
return TRUE;
} catch (Exception\InvalidTemplateResourceException $e) {
return FALSE;
}
}
/**
* Processes following placeholders inside $pattern:
* - "#templateRoot"
* - "#partialRoot"
* - "#layoutRoot"
* - "#subpackage"
* - "#controller"
* - "#format"
*
* This method is used to generate "fallback chains" for file system locations where a certain Partial can reside.
*
* If $bubbleControllerAndSubpackage is FALSE and $formatIsOptional is FALSE, then the resulting array will only have one element
* with all the above placeholders replaced.
*
* If you set $bubbleControllerAndSubpackage to TRUE, then you will get an array with potentially many elements:
* The first element of the array is like above. The second element has the # controller part set to "" (the empty string)
* The third element now has the # controller part again stripped off, and has the last subpackage part stripped off as well.
* This continues until both "#subpackage" and "#controller" are empty.
*
* Example for $bubbleControllerAndSubpackage is TRUE, we have the Tx_MyExtension_MySubPackage_Controller_MyController
* as Controller Object Name and the current format is "html"
*
* If pattern is "#templateRoot/#subpackage/#controller/#action.#format", then the resulting array is:
* - "Resources/Private/Templates/MySubPackage/My/#action.html"
* - "Resources/Private/Templates/MySubPackage/#action.html"
* - "Resources/Private/Templates/#action.html"
*
* If you set $formatIsOptional to TRUE, then for any of the above arrays, every element will be duplicated - once with "#format"
* replaced by the current request format, and once with ."#format" stripped off.
*
* #param string $pattern Pattern to be resolved
* #param bool $bubbleControllerAndSubpackage if TRUE, then we successively split off parts from "#controller" and "#subpackage" until both are empty.
* #param bool $formatIsOptional if TRUE, then half of the resulting strings will have ."#format" stripped off, and the other half will have it.
* #return array unix style paths
*/
protected function expandGenericPathPattern($pattern, $bubbleControllerAndSubpackage, $formatIsOptional) {
$paths = array($pattern);
$this->expandPatterns($paths, '#templateRoot', $this->getTemplateRootPaths());
$this->expandPatterns($paths, '#partialRoot', $this->getPartialRootPaths());
$this->expandPatterns($paths, '#layoutRoot', $this->getLayoutRootPaths());
/** #var $actionRequest \TYPO3\CMS\Extbase\Mvc\Request */
$actionRequest = $this->controllerContext->getRequest();
$subpackageKey = $actionRequest->getControllerSubpackageKey();
$controllerName = $actionRequest->getControllerName();
if ($subpackageKey !== NULL) {
if (strpos($subpackageKey, Fluid::NAMESPACE_SEPARATOR) !== FALSE) {
$namespaceSeparator = Fluid::NAMESPACE_SEPARATOR;
} else {
$namespaceSeparator = Fluid::LEGACY_NAMESPACE_SEPARATOR;
}
$subpackageKeyParts = explode($namespaceSeparator, $subpackageKey);
} else {
$subpackageKeyParts = array();
}
if ($bubbleControllerAndSubpackage) {
$numberOfPathsBeforeSubpackageExpansion = count($paths);
$numberOfSubpackageParts = count($subpackageKeyParts);
$subpackageReplacements = array();
for ($i = 0; $i <= $numberOfSubpackageParts; $i++) {
$subpackageReplacements[] = implode('/', ($i < 0 ? $subpackageKeyParts : array_slice($subpackageKeyParts, $i)));
}
$this->expandPatterns($paths, '#subpackage', $subpackageReplacements);
for ($i = ($numberOfPathsBeforeSubpackageExpansion - 1) * ($numberOfSubpackageParts + 1); $i >= 0; $i -= ($numberOfSubpackageParts + 1)) {
array_splice($paths, $i, 0, str_replace('#controller', $controllerName, $paths[$i]));
}
$this->expandPatterns($paths, '#controller', array(''));
} else {
$i = $controllerName === NULL ? 0 : -1;
$this->expandPatterns($paths, '#subpackage', array(implode('/', $i < 0 ? $subpackageKeyParts :
array_slice($subpackageKeyParts, $i))));
$this->expandPatterns($paths, '#controller', array($controllerName));
}
if ($formatIsOptional) {
$this->expandPatterns($paths, '.#format', array('.' . $actionRequest->getFormat(), ''));
$this->expandPatterns($paths, '#format', array($actionRequest->getFormat(), ''));
} else {
$this->expandPatterns($paths, '.#format', array('.' . $actionRequest->getFormat()));
$this->expandPatterns($paths, '#format', array($actionRequest->getFormat()));
}
return array_values(array_unique($paths));
}
/**
* Expands the given $patterns by adding an array element for each $replacement
* replacing occurrences of $search.
*
* #param array $patterns
* #param string $search
* #param array $replacements
* #return void
*/
protected function expandPatterns(array &$patterns, $search, array $replacements) {
$patternsWithReplacements = array();
foreach ($patterns as $pattern) {
foreach ($replacements as $replacement) {
$patternsWithReplacements[] = GeneralUtility::fixWindowsFilePath(str_replace($search, $replacement, $pattern));
}
}
$patterns = $patternsWithReplacements;
}
/**
* Returns a unique identifier for the given file in the format
* <PackageKey>_<SubPackageKey>_<ControllerName>_<prefix>_<SHA1>
* The SH1 hash is a checksum that is based on the file path and last modification date
*
* #param string $pathAndFilename
* #param string $prefix
* #return string
*/
protected function createIdentifierForFile($pathAndFilename, $prefix) {
/** #var $actionRequest \TYPO3\CMS\Extbase\Mvc\Request */
$actionRequest = $this->controllerContext->getRequest();
$extensionName = $actionRequest->getControllerExtensionName();
$subPackageKey = $actionRequest->getControllerSubpackageKey();
if ($subPackageKey !== NULL) {
$extensionName .= '_' . $subPackageKey;
}
$controllerName = $actionRequest->getControllerName();
$templateModifiedTimestamp = filemtime($pathAndFilename);
$templateIdentifier = sprintf('%s_%s_%s_%s', $extensionName, $controllerName, $prefix, sha1($pathAndFilename . '|' . $templateModifiedTimestamp));
return $templateIdentifier;
}
/**
* Wrapper method to make the static call to GeneralUtility mockable in tests
*
* #param string $pathAndFilename
*
* #return string absolute pathAndFilename
*/
protected function resolveFileNamePath($pathAndFilename) {
return GeneralUtility::getFileAbsFileName(GeneralUtility::fixWindowsFilePath($pathAndFilename), TRUE);
}
}
$templatePathAndFilename = $this->getTemplatePathAndFilename($actionName);
This is the bad one in the function "getTemplateSource".
I downgraded the php version to 5.5 (new xampp installation) and it didn't work. :-(
Hoping for help,
thanks!
Okay I think the problem is solved.
The problem was that the column "tx_fluidpages_layout" of the table "pages" in the database had no entry. It was NULL.
Because I could not change and save it in the page properties without calling that error I changed it with phpmyadmin.
To fix that error you have to manually go to the table "pages" in the database f.e. with phpmyadmin and then to the column "tx_fluidpages_layout". There you have to edit the value and change it to "fluidpages__fluidpages". After that you can save it and reload the backend.
Now you should edit the page properties and set your page layout which comes from your provider extension.
I think it is a bug anyway, that should not happened. In TYPO3 6.x it was inserted automatically.

Php class exception error message

I'm struggling with fixing this class exception error. If anyone could help it would be greatly appreciated, Thanks!
BACKGROUND INFO:
After installing a Dashnex plugin on my wordpress site & then uninstalling WP Quick cache I am getting this error message. Please note that quick cache is fully uninstalled & the wp-config.php file includes no quick cache instructions.
ERROR MESSAGE:
Fatal error: Uncaught exception 'ReflectionException' with message 'Class \quick_cache does not exist' in /home/cal108/public_html/wp-content/plugins/dashnex-plugin/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/AnnotationDriver.php:246 Stack trace: #0 /home/cal108/public_html/wp-content/plugins/dashnex-plugin/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/AnnotationDriver.php(246): ReflectionClass->__construct('\quick_cache') #1 /home/cal108/public_html/wp-content/plugins/dashnex-plugin/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php(113): Doctrine\Common\Persistence\Mapping\Driver\AnnotationDriver->getAllClassNames() #2 /home/cal108/public_html/wp-content/plugins/dashnex-plugin/DashNex/Doctrine/MagicSchema.php(18): Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory->getAllMetadata() #3 /home/cal108/public_html/wp-content/plugins/dashnex-plugin/DashNex/Doctrine/MagicSchema.php(37): DashNex\Doctrine\MagicSchema->Get in /home/cal108/public_html/wp-content/plugins/dashnex-plugin/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/Driver/AnnotationDriver.php on line 246
AnnotationDriver.php Line 246
$rc = new \ReflectionClass($className);
AnnotationDriver.php File
<?php
abstract class AnnotationDriver implements MappingDriver
{
/**
* The AnnotationReader.
*
* #var AnnotationReader
*/
protected $reader;
/**
* The paths where to look for mapping files.
*
* #var array
*/
protected $paths = array();
/**
* The paths excluded from path where to look for mapping files.
*
* #var array
*/
protected $excludePaths = array();
/**
* The file extension of mapping documents.
*
* #var string
*/
protected $fileExtension = '.php';
/**
* Cache for AnnotationDriver#getAllClassNames().
*
* #var array|null
*/
protected $classNames;
/**
* Name of the entity annotations as keys.
*
* #var array
*/
protected $entityAnnotationClasses = array();
/**
* Initializes a new AnnotationDriver that uses the given AnnotationReader for reading
* docblock annotations.
*
* #param AnnotationReader $reader The AnnotationReader to use, duck-typed.
* #param string|array|null $paths One or multiple paths where mapping classes can be found.
*/
public function __construct($reader, $paths = null)
{
$this->reader = $reader;
if ($paths) {
$this->addPaths((array) $paths);
}
}
/**
* Appends lookup paths to metadata driver.
*
* #param array $paths
*
* #return void
*/
public function addPaths(array $paths)
{
$this->paths = array_unique(array_merge($this->paths, $paths));
}
/**
* Retrieves the defined metadata lookup paths.
*
* #return array
*/
public function getPaths()
{
return $this->paths;
}
/**
* Append exclude lookup paths to metadata driver.
*
* #param array $paths
*/
public function addExcludePaths(array $paths)
{
$this->excludePaths = array_unique(array_merge($this->excludePaths, $paths));
}
/**
* Retrieve the defined metadata lookup exclude paths.
*
* #return array
*/
public function getExcludePaths()
{
return $this->excludePaths;
}
/**
* Retrieve the current annotation reader
*
* #return AnnotationReader
*/
public function getReader()
{
return $this->reader;
}
/**
* Gets the file extension used to look for mapping files under.
*
* #return string
*/
public function getFileExtension()
{
return $this->fileExtension;
}
/**
* Sets the file extension used to look for mapping files under.
*
* #param string $fileExtension The file extension to set.
*
* #return void
*/
public function setFileExtension($fileExtension)
{
$this->fileExtension = $fileExtension;
}
/**
* Returns whether the class with the specified name is transient. Only non-transient
* classes, that is entities and mapped superclasses, should have their metadata loaded.
*
* A class is non-transient if it is annotated with an annotation
* from the {#see AnnotationDriver::entityAnnotationClasses}.
*
* #param string $className
*
* #return boolean
*/
public function isTransient($className)
{
$classAnnotations = $this->reader->getClassAnnotations(new \ReflectionClass($className));
foreach ($classAnnotations as $annot) {
if (isset($this->entityAnnotationClasses[get_class($annot)])) {
return false;
}
}
return true;
}
/**
* {#inheritDoc}
*/
public function getAllClassNames()
{
if ($this->classNames !== null) {
return $this->classNames;
}
if (!$this->paths) {
throw MappingException::pathRequired();
}
$classes = array();
$includedFiles = array();
foreach ($this->paths as $path) {
if ( ! is_dir($path)) {
throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path);
}
$iterator = new \RegexIterator(
new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($path, \FilesystemIterator::SKIP_DOTS),
\RecursiveIteratorIterator::LEAVES_ONLY
),
'/^.+' . preg_quote($this->fileExtension) . '$/i',
\RecursiveRegexIterator::GET_MATCH
);
foreach ($iterator as $file) {
$sourceFile = $file[0];
if ( ! preg_match('(^phar:)i', $sourceFile)) {
$sourceFile = realpath($sourceFile);
}
foreach ($this->excludePaths as $excludePath) {
$exclude = str_replace('\\', '/', realpath($excludePath));
$current = str_replace('\\', '/', $sourceFile);
if (strpos($current, $exclude) !== false) {
continue 2;
}
}
require_once $sourceFile;
$includedFiles[] = $sourceFile;
}
}
$declared = get_declared_classes();
foreach ($declared as $className) {
$rc = new \ReflectionClass($className);
$sourceFile = $rc->getFileName();
if (in_array($sourceFile, $includedFiles) && ! $this->isTransient($className)) {
$classes[] = $className;
}
}
$this->classNames = $classes;
return $classes;
}
}
I WAS ABLE TO SOLVE MY PROBLEM. HELP NOT NEEDED ANYMORE :)
FOR ANYONE THIS MAY STILL HELP:
I DISABLED ALL OF MY PLUGINS BY RENAMING THEM IT IN CPANEL, THEN BROUGHT EACH ONE ONLINE AGAIN TO KNOW IF THE DASHNEX PLUGIN WAS THE CULPRIT. IT WAS. THEN RENAMED ALL PLUGINS AGAIN & ALL WORKING FINE.
I DON'T THINK THE DASHNEX PLUGIN LIKED MY UNINSTALLING WP QUICK CACHE. BUT REINSTALLING IT AFTER WP QUCIK CACHE HAD ALREADY BEEN UNINSTALLED WORKED FINE. THIS IS THE 2ND TIME I'VE HAD PROBLEMS WHEN QUICK CACHE HAS BEEN UNINSTALLED SO BE WARY OF IT. MAYBE BEST TO JUST DEACTIVATE IT & ONLY UNINSTALL IT ON A BRAND NEW SITE BEFORE INSTALLING ANY OTHER PLUGINS.
DIDN'T END UP NEEDING TO TWEAK THE PHP CODE.

Categories