Trying to include a php file in a script and even though the page loads without showing or logging errors, the included file is not executed.
I have created a test file that looks like this:
<?php
$sale_amount = '10.00';
$product = 'Drive-Plan';
include('partners/controller/record-sale.php');
echo "commission counted"
?>
opening this file in browser completes the expected function.
Trying to include this same code in my script does not complete the function.
original script works good:
/**
* Swap current users plan to a new one.
*
* #return \Illuminate\Contracts\Routing\ResponseFactory|\Symfony\Component\HttpFoundation\Response
*/
public function swapPlan() {
if ($this->user->subscribed() && Input::get('plan')) {
$this->user->subscription(Input::get('plan'))->swap();
return response(trans('app.planSwapSuccess', ['plan' => Input::get('plan')]), 200);
}
}
Including my file in this script does not have the expected effect.
/**
* Swap current users plan to a new one.
*
* #return \Illuminate\Contracts\Routing\ResponseFactory|\Symfony\Component\HttpFoundation\Response
*/
public function swapPlan() {
if ($this->user->subscribed() && Input::get('plan')) {
$this->user->subscription(Input::get('plan'))->swap();
return response(trans('app.planSwapSuccess', ['plan' => Input::get('plan')]), 200);
$sale_amount = '10.00';
$product = 'Drive-Plan';
include('partners/controller/record-sale.php');
}
}
The page will complete loading without errors, however the function that should be completed by the included file is not executed. Any Ideas on what I may have done wrong are appreciated.
I have spent a few days trying to figure this out. Since my test file works I'm guessing I'm missing something obvious in the full script.
Thanks for looking.
Comeplete file:
<?php namespace App\Http\Controllers;
use App;
use Auth;
use Input;
use Stripe\Stripe;
use Stripe\Plan;
class PaymentsController extends Controller {
public function __construct() {
$this->middleware('loggedIn');
$this->middleware('paymentsEnabled');
$this->user = Auth::user();
$this->settings = App::make('App\Services\Settings');
Stripe::setApiKey($this->settings->get('stripe_secret_key'));
}
/**
* Subscribe user to a plan or swap him to a different plan.
*
* #return response
*/
public function upgrade() {
if ($this->user->subscribed()) {
$this->user->subscription(Input::get('plan'))->swap();
} else {
$this->user->subscription(Input::get('plan'))->create(Input::get('stripe_token'), ['email' => $this->user->email]);
}
return response(trans('app.upgradeSuccess'), 200);
$sale_amount = '10.00';
$product = 'Drive-Plan';
include('partners/controller/record-sale.php');
}
/**
* Swap current users plan to a new one.
*
* #return \Illuminate\Contracts\Routing\ResponseFactory|\Symfony\Component\HttpFoundation\Response
*/
public function swapPlan() {
if ($this->user->subscribed() && Input::get('plan')) {
$this->user->subscription(Input::get('plan'))->swap();
return response(trans('app.planSwapSuccess', ['plan' => Input::get('plan')]), 200);
$sale_amount = '10.00';
$product = 'Drive-Plan';
include('partners/controller/record-sale.php');
}
}
/**
* Attach new credit card to user.
*
* #return \Illuminate\Contracts\Routing\ResponseFactory|\Symfony\Component\HttpFoundation\Response
*/
public function addNewCard() {
$this->user->updateCard(Input::get('stripe_token'));
return response(trans('app.cardAddSuccess'), 200);
}
/**
* Resume a canceled subscription.
*/
public function resumeSubscription() {
$this->user->subscription(Input::get('plan'))->resume(Input::get('token'));
return $this->user;
$sale_amount = '10.00';
$product = 'Drive-Plan';
include('partners/controller/record-sale.php');
}
/**
* Cancel users subscription.
*
* #return \App\User
*/
public function unsubscribe() {
$this->user->subscription()->cancel();
return $this->user;
}
/**
* Return current users invoices.
*
* #return array
*/
public function getInvoices() {
return view('invoices')->with('invoices', $this->user->invoices())->with('settings', $this->settings);
}
/**
* Download invoice with given id.
*
* #param {int|string} $id
* #return \Symfony\Component\HttpFoundation\Response
*/
public function downloadInvoice($id) {
return $this->user->downloadInvoice($id, [
'vendor' => $this->settings->get('invoiceVendor'),
'product' => $this->settings->get('invoiceProduct'),
]);
}
/**
* Return all created plans.
*
* #return array
*/
public function getPlans() {
$plans = Plan::all();
$formatted = [];
foreach($plans->data as $plan) {
$formatted[] = [
'interval' => $plan['interval'],
'name' => $plan['name'],
'amount' => $plan['amount'] / 100,
'currency' => $plan['currency'],
'id' => $plan['id'],
'created' => $plan['created'],
];
}
usort($formatted, function($a1, $a2) {
if ($a1['created'] == $a2['created']) return 0;
return ($a1['created'] < $a2['created']) ? -1 : 1;
});
return $formatted;
}
}
Your method ends on return, meaning your include in the methods and variables being set are never reached.
An example:
Moving said include and variables to before the return should solve the issue.
/**
* Resume a canceled subscription.
*/
public function resumeSubscription() {
$this->user->subscription(Input::get('plan'))->resume(Input::get('token'));
// Moved to before return
$sale_amount = '10.00';
$product = 'Drive-Plan';
include('partners/controller/record-sale.php');
return $this->user;
// UNREACHABLE
//$sale_amount = '10.00';
//$product = 'Drive-Plan';
//include('partners/controller/record-sale.php');
}
Related
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
I have a scenario like this:
The system handles reservations from couple of different sources. All bookings come in the form of a json with differing formats for each source. Some JSON attributes are present in one JSON and not in the other etc.
In order to enter the reservation into the system, I am trying to centralize the Add Reservation logic into one method. To do this, I am trying to create a class called Reservation using the Builder pattern as such:
<?php
namespace App\Business\Classes\Reservation;
use App\Business\Classes\Utils\ReservationUtils;
/**
* Class Reservation
* Holds entire reservation details
* #package App\Business\Classes\Reservation
*/
class Reservation
{
protected $reference, $otaReference, $hotelCode, $customerId, $guestName, $couponId, $checkin, $checkout, $guests, $customerCountry,
$commissionRate, $paymentStatus, $commissionOta, $commissionDifference, $rooms = [], $cityTax, $vat, $serviceCharge, $geniusBooker = false,
$geniusAmount = 0, $taxes, $taxIncluded = false, $supplierAmount, $totalAmount, $specialRequest, $currency, $deviceType, $bookingSource,
$otaRefId, $status, $source, $remarks;
public function __construct()
{
// generates a reference
$this->reference = ReservationUtils::referenceGenerator();
}
/**
* #param mixed $otaReference
* #return Reservation
*/
public function setOtaReference($otaReference): Reservation
{
$this->otaReference = $otaReference;
return $this;
}
/**
* #param mixed $checkin
* #return Reservation
*/
public function setCheckin($checkin): Reservation
{
$this->checkin = $checkin;
return $this;
}
/**
* #param mixed $checkout
* #return Reservation
*/
public function setCheckout($checkout): Reservation
{
$this->checkout = $checkout;
return $this;
}
/**
* #param array $rooms
* #return Reservation
*/
public function setRooms(array $rooms): Reservation
{
$this->rooms = $rooms;
return $this;
}
// and so on....
}
And I would use it like this:
$data= json_decode($result->jsonData);
$reservation = (new Reservation())
->setOtaReference($data->otaReference)
->setCheckin($data->checkin)
->setCheckout($data->checkout); //...etc
This is probably not the textbook usage of the builder pattern in PHP or even Java but is there anything wrong with it?
Thanks
I'm trying to "use" a vendor script to connect to feefo api (an online reviews service) but when I try and use the script it gives me this error:
Type error: Argument 1 passed to
BlueBayTravel\Feefo\Feefo::__construct() must be an instance of
GuzzleHttp\Client, null given, called in/Users/webuser1/Projects/_websites/domain.co.uk/plugins/gavinfoster/feefo/components/Feedback.php on line 47
Here is the vendor code I'm using:
/*
* This file is part of Feefo.
*
* (c) Blue Bay Travel <developers#bluebaytravel.co.uk>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace BlueBayTravel\Feefo;
use ArrayAccess;
use Countable;
use Exception;
use GuzzleHttp\Client;
use Illuminate\Contracts\Config\Repository;
use Illuminate\Contracts\Support\Arrayable;
use SimpleXMLElement;
/**
* This is the feefo class.
*
* #author James Brooks <james#bluebaytravel.co.uk>
*/
class Feefo implements Arrayable, ArrayAccess, Countable
{
/**
* The guzzle client.
*
* #var \GuzzleHttp\Client
*/
protected $client;
/**
* The config repository.
*
* #var \Illuminate\Contracts\Config\Repository
*/
protected $config;
/**
* The review items.
*
* #var array
*/
protected $data;
/**
* Create a new feefo instance.
*
* #param \GuzzleHttp\Client $client
* #param \Illuminate\Contracts\Config\Repository $config
*
* #return void
*/
public function __construct(Client $client, Repository $config)
{
$this->client = $client;
$this->config = $config;
}
/**
* Fetch feedback.
*
* #param array|null $params
*
* #return \BlueBayTravel\Feefo\Feefo
*/
public function fetch($params = null)
{
if ($params === null) {
$params['json'] = true;
$params['mode'] = 'both';
}
$params['logon'] = $this->config->get('feefo.logon');
$params['password'] = $this->config->get('feefo.password');
try {
$body = $this->client->get($this->getRequestUrl($params));
return $this->parse((string) $body->getBody());
} catch (Exception $e) {
throw $e; // Re-throw the exception
}
}
/**
* Parses the response.
*
* #param string $data
*
* #return \Illuminate\Support\Collection
*/
protected function parse($data)
{
$xml = new SimpleXMLElement($data);
foreach ((array) $xml as $items) {
if (isset($items->TOTALRESPONSES)) {
continue;
}
foreach ($items as $item) {
$this->data[] = new FeefoItem((array) $item);
}
}
return $this;
}
/**
* Assigns a value to the specified offset.
*
* #param mixed $offset
* #param mixed $value
*
* #return void
*/
public function offsetSet($offset, $value)
{
if (is_null($offset)) {
$this->data[] = $value;
} else {
$this->data[$offset] = $value;
}
}
/**
* Whether or not an offset exists.
*
* #param mixed $offset
*
* #return bool
*/
public function offsetExists($offset)
{
return isset($this->data[$offset]);
}
/**
* Unsets an offset.
*
* #param mixed $offset
*
* #return void
*/
public function offsetUnset($offset)
{
if ($this->offsetExists($offset)) {
unset($this->data[$offset]);
}
}
/**
* Returns the value at specified offset.
*
* #param mixed $offset
*
* #return mixed
*/
public function offsetGet($offset)
{
return $this->offsetExists($offset) ? $this->data[$offset] : null;
}
/**
* Count the number of items in the dataset.
*
* #return int
*/
public function count()
{
return count($this->data);
}
/**
* Get the instance as an array.
*
* #return array
*/
public function toArray()
{
return $this->data;
}
/**
* Returns the Feefo API endpoint.
*
* #param array $params
*
* #return string
*/
protected function getRequestUrl(array $params)
{
$query = http_build_query($params);
return sprintf('%s?%s', $this->config->get('feefo.baseuri'), $query);
}
}
And here is the code I'm using to try and use the fetch() method from the vendor class:
use Cms\Classes\ComponentBase;
use ArrayAccess;
use Countable;
use Exception;
use GuzzleHttp\Client;
use Illuminate\Contracts\Config\Repository;
use Illuminate\Contracts\Support\Arrayable;
use SimpleXMLElement;
use BlueBayTravel\Feefo\Feefo;
class Feedback extends ComponentBase
{
public $client;
public $config;
/**
* Container used for display
* #var BlueBayTravel\Feefo
*/
public $feedback;
public function componentDetails()
{
return [
'name' => 'Feedback Component',
'description' => 'Adds Feefo feedback to the website'
];
}
public function defineProperties()
{
return [];
}
public function onRun()
{
$this->feedback = $this->page['feedback'] = $this->loadFeedback($this->client, $this->config);
}
public function loadFeedback($client, $config)
{
$feefo = new Feefo($client, $config);
$feedback = $feefo->fetch();
return $feedback;
}
}
Won't allow me to call the Fetch() method statically so trying to instantiate and then use:
public function loadFeedback($client, $config)
{
$feefo = new Feefo($client, $config);
$feedback = $feefo->fetch();
return $feedback;
}
I've also tried type hinting the args like this:
public function loadFeedback(Client $client, Repository $config)
{
$feefo = new Feefo($client, $config);
$feedback = $feefo->fetch();
return $feedback;
}
But still I get the exception error above. I'm struggling to understand how to get past this. Any help for a newbie much appreciated :)
Just type hinting the function won't cast it to that object type. You need to properly pass the Guzzle\Client object to your function call.
// Make sure you 'use' the GuzzleClient on top of the class
// or use the Fully Qualified Class Name of the Client
$client = new Client();
$feedback = new Feedback();
// Now we passed the Client object to the function of the feedback class
// which will lead to the constructor of the Feefo class which is
// where your error is coming from.
$loadedFeedback = $feedback->loadFeedback($client);
Don't forget to do the same for the Repository $config from Laravel/Lumen
I've setup my server with Yii2 and Humhub ext,
What i'm trying to do is set a rest api to it , but I get 500 Internal server error :
"message": "Cannot declare class humhub\modules\content\models\Content, because the name is already in use",
"file": "***\content\models\Content.php",
The first class is :
<?php
namespace app\models;
use Yii;
include '../humhub/modules/content/models/content.php';
class Content extends \humhub\modules\content\models\Content
{
public function getPosts()
{
return $this->hasMany(Post::className(), ['id' => 'object_id']);
}
}
The second class is (pretty big):
<?php
/**
* #link https://www.humhub.org/
* #copyright Copyright (c) 2017 HumHub GmbH & Co. KG
* #license https://www.humhub.com/licences
*/
namespace humhub\modules\content\models;
include __DIR__ .'/../../../modules\content\models\ContentDeprecated.php';
use Yii;
use humhub\modules\user\components\PermissionManager;
use yii\base\Exception;
use yii\helpers\Url;
use humhub\modules\user\models\User;
use humhub\modules\space\models\Space;
use humhub\modules\content\components\ContentActiveRecord;
use humhub\modules\content\components\ContentContainerActiveRecord;
use humhub\modules\content\permissions\ManageContent;
use yii\rbac\Permission;
/**
* This is the model class for table "content".
*
*
* The followings are the available columns in table 'content':
* #property integer $id
* #property string $guid
* #property string $object_model
* #property integer $object_id
* #property integer $visibility
* #property integer $pinned
* #property string $archived
* #property string $created_at
* #property integer $created_by
* #property string $updated_at
* #property integer $updated_by
* #property ContentContainer $contentContainer
*
* #since 0.5
*/
class Content extends ContentDeprecated
{
/**
* A array of user objects which should informed about this new content.
*
* #var array User
*/
public $notifyUsersOfNewContent = [];
/**
* #var int The private visibility mode (e.g. for space member content or user profile posts for friends)
*/
const VISIBILITY_PRIVATE = 0;
/**
* #var int Public visibility mode, e.g. content which are visibile for followers
*/
const VISIBILITY_PUBLIC = 1;
/**
* #var int Owner visibility mode, only visible for contentContainer + content owner
*/
const VISIBILITY_OWNER = 2;
/**
* #var ContentContainerActiveRecord the Container (e.g. Space or User) where this content belongs to.
*/
protected $_container = null;
/**
* #inheritdoc
*/
public function behaviors()
{
return [
[
'class' => \humhub\components\behaviors\PolymorphicRelation::className(),
'mustBeInstanceOf' => array(ContentActiveRecord::className()),
],
[
'class' => \humhub\components\behaviors\GUID::className(),
],
];
}
/**
* #inheritdoc
*/
public static function tableName()
{
return 'content';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['object_id', 'visibility', 'pinned'], 'integer'],
[['archived'], 'safe'],
[['guid'], 'string', 'max' => 45],
[['object_model'], 'string', 'max' => 100],
[['object_model', 'object_id'], 'unique', 'targetAttribute' => ['object_model', 'object_id'], 'message' => 'The combination of Object Model and Object ID has already been taken.'],
[['guid'], 'unique']
];
}
/**
* Returns a Content Object by given Class and ID
*
* #param string $className Class Name of the Content
* #param int $id Primary Key
*/
public static function Get($className, $id)
{
$content = self::findOne(['object_model' => $className, 'object_id' => $id]);
if ($content != null) {
return $className::findOne(['id' => $id]);
}
return null;
}
/**
* #inheritdoc
*/
public function beforeSave($insert)
{
if ($this->object_model == "" || $this->object_id == "") {
throw new Exception("Could not save content with object_model or object_id!");
}
// Set some default values
if (!$this->archived) {
$this->archived = 0;
}
if (!$this->visibility) {
$this->visibility = self::VISIBILITY_PRIVATE;
}
if (!$this->pinned) {
$this->pinned = 0;
}
if ($insert) {
if ($this->created_by == "") {
$this->created_by = Yii::$app->user->id;
}
}
$this->stream_sort_date = new \yii\db\Expression('NOW()');
if ($this->created_by == "") {
throw new Exception("Could not save content without created_by!");
}
return parent::beforeSave($insert);
}
/**
* #inheritdoc
*/
public function afterSave($insert, $changedAttributes)
{
$contentSource = $this->getPolymorphicRelation();
foreach ($this->notifyUsersOfNewContent as $user) {
$contentSource->follow($user->id);
}
if ($insert && !$contentSource instanceof \humhub\modules\activity\models\Activity) {
if ($this->container !== null) {
$notifyUsers = array_merge($this->notifyUsersOfNewContent, Yii::$app->notification->getFollowers($this));
\humhub\modules\content\notifications\ContentCreated::instance()
->from($this->user)
->about($contentSource)
->sendBulk($notifyUsers);
\humhub\modules\content\activities\ContentCreated::instance()
->about($contentSource)->save();
Yii::$app->live->send(new \humhub\modules\content\live\NewContent([
'sguid' => ($this->container instanceof Space) ? $this->container->guid : null,
'uguid' => ($this->container instanceof User) ? $this->container->guid : null,
'originator' => $this->user->guid,
'contentContainerId' => $this->container->contentContainerRecord->id,
'visibility' => $this->visibility,
'contentId' => $this->id
]));
}
}
return parent::afterSave($insert, $changedAttributes);
}
/**
* #inheritdoc
*/
public function afterDelete()
{
// Try delete the underlying object (Post, Question, Task, ...)
$this->resetPolymorphicRelation();
if ($this->getPolymorphicRelation() !== null) {
$this->getPolymorphicRelation()->delete();
}
parent::afterDelete();
}
/**
* Returns the visibility of the content object
*
* #return Integer
*/
public function getVisibility()
{
return $this->visibility;
}
/**
* Checks if the content visiblity is set to public.
*
* #return boolean
*/
public function isPublic()
{
return $this->visibility == self::VISIBILITY_PUBLIC;
}
/**
* Checks if the content visiblity is set to private.
*
* #return boolean
*/
public function isPrivate()
{
return $this->visibility == self::VISIBILITY_PRIVATE;
}
/**
* Checks if the content object is pinned
*
* #return Boolean
*/
public function isPinned()
{
return ($this->pinned);
}
/**
* Pins the content object
*/
public function pin()
{
$this->pinned = 1;
//This prevents the call of beforesave, and the setting of update_at
$this->updateAttributes(['pinned']);
}
/**
* Unpins the content object
*/
public function unpin()
{
$this->pinned = 0;
$this->updateAttributes(['pinned']);
}
/**
* Checks if the user can pin this content.
* This is only allowed for workspace owner.
*
* #return boolean
*/
public function canPin()
{
if ($this->isArchived()) {
return false;
}
return $this->getContainer()->permissionManager->can(new ManageContent());
}
/**
* Creates a list of pinned content objects of the wall
*
* #return Int
*/
public function countPinnedItems()
{
return Content::find()->where(['content.contentcontainer_id' => $this->contentcontainer_id, 'content.pinned' => 1])->count();
}
/**
* Checks if current content object is archived
*
* #return boolean
*/
public function isArchived()
{
return $this->archived || ($this->getContainer() !== null && $this->getContainer()->isArchived());
}
/**
* Checks if the current user can archive this content.
* The content owner and the workspace admin can archive contents.
*
* #return boolean
*/
public function canArchive()
{
// Disabled on user profiles, there is no stream filter available yet.
if ($this->getContainer() instanceof User) {
return false;
}
return $this->getContainer()->permissionManager->can(new ManageContent());
}
/**
* Archives the content object
*/
public function archive()
{
if ($this->canArchive()) {
if ($this->isPinned()) {
$this->unpin();
}
$this->archived = 1;
if (!$this->save()) {
throw new Exception("Could not archive content!" . print_r($this->getErrors(), 1));
}
}
}
/**
* Unarchives the content object
*/
public function unarchive()
{
if ($this->canArchive()) {
$this->archived = 0;
$this->save();
}
}
/**
* Returns the url of this content.
*
* By default is returns the url of the wall entry.
*
* Optionally it's possible to create an own getUrl method in the underlying
* HActiveRecordContent (e.g. Post) to overwrite this behavior.
* e.g. in case there is no wall entry available for this content.
*
* #since 0.11.1
*/
public function getUrl()
{
if (method_exists($this->getPolymorphicRelation(), 'getUrl')) {
return $this->getPolymorphicRelation()->getUrl();
}
return Url::toRoute(['/content/perma', 'id' => $this->id]);
}
/**
* Sets container (e.g. space or user record) for this content.
*
* #param ContentContainerActiveRecord $container
* #throws Exception
*/
public function setContainer(ContentContainerActiveRecord $container)
{
$this->contentcontainer_id = $container->contentContainerRecord->id;
$this->_container = $container;
}
/**
* Returns the content container (e.g. space or user record) of this content
*
* #return ContentContainerActiveRecord
* #throws Exception
*/
public function getContainer()
{
if ($this->_container != null) {
return $this->_container;
}
if ($this->contentContainer !== null) {
$this->_container = $this->contentContainer->getPolymorphicRelation();
}
return $this->_container;
}
/**
* Relation to ContentContainer model
* Note: this is not a Space or User instance!
*
* #since 1.1
* #return \yii\db\ActiveQuery
*/
public function getContentContainer()
{
return $this->hasOne(ContentContainer::className(), ['id' => 'contentcontainer_id']);
}
/**
* Checks if the given user can edit this content.
*
* A user can edit a content if one of the following conditions are met:
*
* - User is the owner of the content
* - User is system administrator and the content module setting `adminCanEditAllContent` is set to true (default)
* - The user is granted the managePermission set by the model record class
* - The user meets the additional condition implemented by the model records class own `canEdit()` function.
*
* #since 1.1
* #param User $user
* #return bool can edit this content
*/
public function canEdit($user = null)
{
if (Yii::$app->user->isGuest) {
return false;
}
if ($user === null) {
$user = Yii::$app->user->getIdentity();
}
// Only owner can edit his content
if ($user !== null && $this->created_by == $user->id) {
return true;
}
// Global Admin can edit/delete arbitrarily content
if (Yii::$app->getModule('content')->adminCanEditAllContent && $user->isSystemAdmin()) {
return true;
}
/* #var $model ContentActiveRecord */
$model = $this->getPolymorphicRelation();
// Check additional manage permission for the given container
if ($model->hasManagePermission() && $this->getContainer() && $this->getContainer()->getPermissionManager($user)->can($model->getManagePermission())) {
return true;
}
// Check if underlying models canEdit implementation
// ToDo: Implement this as interface
if (method_exists($model, 'canEdit') && $model->canEdit($user)) {
return true;
}
return false;
}
/**
* Checks the given $permission of the current user in the contents content container.
* This is short for `$this->getContainer()->getPermissionManager()->can()`.
*
* #param $permission
* #param array $params
* #param bool $allowCaching
* #see PermissionManager::can()
* #since 1.2.1
* #return bool
*/
public function can($permission, $params = [], $allowCaching = true)
{
return $this->getContainer()->getPermissionManager()->can($permission, $params, $allowCaching);
}
/**
* Checks if user can view this content.
*
* #since 1.1
* #param User $user
* #return boolean can view this content
*/
public function canView($user = null)
{
if (!$user && !Yii::$app->user->isGuest) {
$user = Yii::$app->user->getIdentity();
}
// Check Guest Visibility
if (!$user) {
return $this->checkGuestAccess();
}
// Public visible content
if ($this->isPublic()) {
return true;
}
// Check system admin can see all content module configuration
if ($user->isSystemAdmin() && Yii::$app->getModule('content')->adminCanViewAllContent) {
return true;
}
if ($this->isPrivate() && $this->getContainer()->canAccessPrivateContent($user)) {
return true;
}
return false;
}
/**
* Determines if a guest user is able to read this content.
* This is the case if all of the following conditions are met:
*
* - The content is public
* - The `auth.allowGuestAccess` module setting is enabled
* - The space or profile visibility is set to VISIBILITY_ALL
*
* #return bool
*/
public function checkGuestAccess()
{
if(!$this->isPublic() || !Yii::$app->getModule('user')->settings->get('auth.allowGuestAccess')) {
return false;
}
// Check container visibility for guests
return ($this->container instanceof Space && $this->container->visibility == Space::VISIBILITY_ALL)
|| ($this->container instanceof User && $this->container->visibility == User::VISIBILITY_ALL);
}
/**
* Updates the wall/stream sorting time of this content for "updated at" sorting
*/
public function updateStreamSortTime()
{
$this->updateAttributes(['stream_sort_date' => new \yii\db\Expression('NOW()')]);
}
}
As you can see the first class extends the second one , I'm rather new to php but i'm guessing that's the issue
UPDATE : I tried using the "use class as " and still the same error , I also tried changing the name of the first class to Content1 just to check and still the same .
The problem occours in the second class from the error report
This is a recurring error in a few places in the server I figure I will solve it here and the rest will be the same ,
Many Thanks!
You included file with exacly same class name, so you have 2 class declarations with name Content in this file. Easiest ways to fix it:
Change one of class name
Start using Yii2 autloader, if you need to include something - there's something wrong in your code. You should be able to access
class only by using namespace. There's small conditions you have to
met:
Each class must be under a namespace (e.g. foo\bar\MyClass)
Each class must be saved in an individual file whose path is determined by the following algorithm:
// $className is a fully qualified class name without the leading backslash
$classFile = Yii::getAlias('#' . str_replace('\\', '/', $className) . '.php');
More about Yii2 autloading: Class Autoloading
I have a site I created that has a blog section and a video section. I had a config file for blog that I tried to share with the video section but it wasn't working properly so I created a separate config for video. and modified my column names for video from
$title and $subtitle
to
$v_title and $v_subtitle.
but when I do I get the following error
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '' for key 'videos_slug_unique'
for some reason a slug is not being produced and this causes the issue. The slug is unique in my table. If I change the variables to how they were
$title and $subtitle
it works, why is that?
this is my Admin videoController
<?php
namespace App\Http\Controllers\Admin;
use App\Jobs\VideoFormFields;
use App\Http\Requests;
use App\Http\Requests\VideoCreateRequest;
use App\Http\Requests\VideoUpdateRequest;
use App\Http\Controllers\Controller;
use App\Video;
class VideoController extends Controller
{
/**
* Display a listing of the posts.
*/
public function index()
{
return view('admin.video.index')
->withVideos(Video::all());
}
/**
* Show the new video form
*/
public function create()
{
$data = $this->dispatch(new VideoFormFields());
return view('admin.video.create', $data);
}
/**
* Store a newly created Video
*
* #param VideoCreateRequest $request
*/
public function store(VideoCreateRequest $request)
{
$video = Video::create($request->videoFillData());
$video->syncTags($request->get('tags', []));
return redirect()
->route('admin.video.index')
->withSuccess('New Video Successfully Created.');
}
/**
* Show the video edit form
*
* #param int $id
* #return Response
*/
public function edit($id)
{
$data = $this->dispatch(new VideoFormFields($id));
return view('admin.video.edit', $data);
}
/**
* Update the Video
*
* #param VideoUpdateRequest $request
* #param int $id
*/
public function update(VideoUpdateRequest $request, $id)
{
$video = Video::findOrFail($id);
$video->fill($request->videoFillData());
$video->save();
$video->syncTags($request->get('tags', []));
if ($request->action === 'continue') {
return redirect()
->back()
->withSuccess('Video saved.');
}
return redirect()
->route('admin.video.index')
->withSuccess('Video saved.');
}
/**
* Remove the specified resource from storage.
*
* #param int $id
* #return Response
*/
public function destroy($id)
{
$video = Video::findOrFail($id);
$video->tags()->detach();
$video->delete();
return redirect()
->route('admin.video.index')
->withSuccess('Video deleted.');
}
}
this is my videoFormFields
<?php
namespace App\Jobs;
use App\Video;
use App\Tag;
use Carbon\Carbon;
use Illuminate\Contracts\Bus\SelfHandling;
class VideoFormFields extends Job implements SelfHandling
{
/**
* The id (if any) of the Post row
*
* #var integer
*/
protected $id;
/**
* List of fields and default value for each field
*
* #var array
*/
protected $fieldList = [
'v_title' => '',
'v_subtitle' => '',
'page_image' => '',
'content' => '',
'meta_description' => '',
'is_draft' => "0",
'publish_date' => '',
'publish_time' => '',
'layout' => 'video.layouts.v_post',
'tags' => [],
];
/**
* Create a new command instance.
*
* #param integer $id
*/
public function __construct($id = null)
{
$this->id = $id;
}
/**
* Execute the command.
*
* #return array of fieldnames => values
*/
public function handle()
{
$fields = $this->fieldList;
if ($this->id) {
$fields = $this->fieldsFromModel($this->id, $fields);
} else {
$when = Carbon::now()->addHour();
$fields['publish_date'] = $when->format('M-j-Y');
$fields['publish_time'] = $when->format('g:i A');
}
foreach ($fields as $fieldName => $fieldValue) {
$fields[$fieldName] = old($fieldName, $fieldValue);
}
return array_merge(
$fields,
['allTags' => Tag::lists('tag')->all()]
);
}
/**
* Return the field values from the model
*
* #param integer $id
* #param array $fields
* #return array
*/
protected function fieldsFromModel($id, array $fields)
{
$video = Video::findOrFail($id);
$fieldNames = array_keys(array_except($fields, ['tags']));
$fields = ['id' => $id];
foreach ($fieldNames as $field) {
$fields[$field] = $video->{$field};
}
$fields['tags'] = $video->tags()->lists('tag')->all();
return $fields;
}
}
this is my videoCreateRequest
<?php
namespace App\Http\Requests;
use Carbon\Carbon;
class VideoCreateRequest extends Request
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'v_title' => 'required',
'v_subtitle' => 'required',
'content_raw' => 'required', // HERE CHANGED
'publish_date' => 'required',
'publish_time' => 'required',
'layout' => 'required',
];
}
/**
* Return the fields and values to create a new VIDEO post from
*/
public function videoFillData()
{
$published_at = new Carbon(
$this->publish_date.' '.$this->publish_time
);
return [
'v_title' => $this->v_title,
'v_subtitle' => $this->v_subtitle,
'page_image' => $this->page_image,
'content_raw' => $this->content_raw, // HERE CHANGED
'meta_description' => $this->meta_description,
'is_draft' => (bool)$this->is_draft,
'published_at' => $published_at,
'layout' => $this->layout,
];
}
}
this is my videoUpdateRequest
class VideoUpdateRequest extends VideoCreateRequest
{
//
}
this is my video model
<?php
namespace App;
use App\Services\Markdowner;
use Illuminate\Database\Eloquent\Model;
use Carbon\Carbon;
use Sofa\Eloquence\Eloquence;
class Video extends Model
{
use Eloquence;
protected $dates = ['published_at'];
protected $fillable = [
'v_title', 'v_subtitle', 'content_raw', 'page_image', 'meta_description',
'layout', 'is_draft', 'published_at',
];
/**
* The many-to-many relationship between posts and tags.
*
* #return BelongsToMany
*/
public function tags()
{
return $this->morphToMany('App\Tag', 'taggable');
}
/**
* Set the title attribute and automatically the slug
*
* #param string $value
*/
public function setTitleAttribute($value)
{
$this->attributes['title'] = $value;
if (! $this->exists) {
$this->setUniqueSlug($value, '');
}
}
/**
* Recursive routine to set a unique slug
*
* #param string $title
* #param mixed $extra
*/
protected function setUniqueSlug($title, $extra)
{
$slug = str_slug($title.'-'.$extra);
if (static::whereSlug($slug)->exists()) {
$this->setUniqueSlug($title, $extra + 1);
return;
}
$this->attributes['slug'] = $slug;
}
/**
* Set the HTML content automatically when the raw content is set
*
* #param string $value
*/
public function setContentRawAttribute($value)
{
$markdown = new Markdowner();
$this->attributes['content_raw'] = $value;
$this->attributes['content_html'] = $markdown->toHTML($value);
}
/**
* Sync tag relation adding new tags as needed
*
* #param array $tags
*/
public function syncTags(array $tags)
{
Tag::addNeededTags($tags);
if (count($tags)) {
$this->tags()->sync(
Tag::whereIn('tag', $tags)->lists('id')->all()
);
return;
}
$this->tags()->detach();
}
/**
* Return the date portion of published_at
*/
public function getPublishDateAttribute($value)
{
return $this->published_at->format('M-j-Y');
}
/**
* Return the time portion of published_at
*/
public function getPublishTimeAttribute($value)
{
return $this->published_at->format('g:i A');
}
/**
* Alias for content_raw
*/
public function getContentAttribute($value)
{
return $this->content_raw;
}
/**
* Return URL to post
*
* #param Tag $tag
* #return string
*/
public function url(Tag $tag = null)
{
$url = url('video/'.$this->slug); // this fixed my problem it was 'blog/'
if ($tag) {
$url .= '?tag='.urlencode($tag->tag);
}
return $url;
}
/**
* Return array of tag links
*
* #param string $base
* #return array
*/
public function tagLinks($base = '/video?tag=%TAG%') // this fixed my problem it was 'blog?tag=%TAG%/'
{
$tags = $this->tags()->lists('tag');
$return = [];
foreach ($tags as $tag) {
$url = str_replace('%TAG%', urlencode($tag), $base);
$return[] = ''.e($tag).'';
}
return $return;
}
/**
* Return next post after this one or null
*
* #param Tag $tag
* #return Post
*/
public function newerPost(Tag $tag = null) // //here newVideo v_index & v_post
{
$query =
static::where('published_at', '>', $this->published_at)
->where('published_at', '<=', Carbon::now())
->where('is_draft', 0)
->orderBy('published_at', 'asc');
if ($tag) {
$query = $query->whereHas('tags', function ($q) use ($tag) {
$q->where('tag', '=', $tag->tag);
});
}
return $query->first();
}
/**
* Return older post before this one or null
*
* #param Tag $tag
* #return Post
*/
public function olderPost(Tag $tag = null) // //here olderVideo v_index & v_post
{
$query =
static::where('published_at', '<', $this->published_at)
->where('is_draft', 0)
->orderBy('published_at', 'desc');
if ($tag) {
$query = $query->whereHas('tags', function ($q) use ($tag) {
$q->where('tag', '=', $tag->tag);
});
}
return $query->first();
}
}
this is my video table
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateVideosTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('videos', function (Blueprint $table) {
$table->increments('id');
$table->string('slug')->unique();
$table->string('v_title');
$table->string('v_subtitle');
$table->text('content_raw');
$table->text('content_html');
$table->string('page_image');
$table->string('meta_description');
$table->boolean('is_draft');
$table->string('layout')
->default('blog.layouts.post');
$table->timestamps();
$table->timestamp('published_at')->index();
});
}
/**
* Reverse the migrations.
*/
public function down()
{
Schema::drop('videos');
}
}
After you changed the column names, your dynamic setters setTitleAttribute and setSubtitleAttribute are not called and the slug does not get updated. You need to change the names of setter methods as well.
public function setVTitleAttribute($value) {
...
}
public function setVSubtitleAttribute($value) {
...
}
it seems you did not refactor title to v_title in the whole class. For example, you should change
public function setTitleAttribute($value)
{
$this->attributes['title'] = $value;
if (! $this->exists) {
$this->setUniqueSlug($value, '');
}
}
to
public function setVTitleAttribute($value)
{
$this->attributes['v_title'] = $value;
if (! $this->exists) {
$this->setUniqueSlug($value, '');
}
}