I am trying to load a custom class in my CakePHP3 project, although I can't seem to find out what I am missing.
I have a folder src/Library with Config.php in it:
<?php
namespace App\Library;
/**
* Class containing CONST values for important settings
*
* #version 1.0
* #author berry
*/
class Config
{
const UPLOAD_DIRECTORY = './upload/';
}
I put use App\Library\Config; in my PicturesController, which Visual Studio even recognizes as a valid class (I can access the const through intellisense)
Here is my controller:
<?php
namespace App\Controller;
use App\Controller\AppController;
use Cake\Filesystem\Folder;
use Cake\Filesystem\File;
use App\Library\Config;
/**
* Pictures Controller
*
* #property \App\Model\Table\PicturesTable $Pictures
*/
class PicturesController extends AppController
{
public function upload()
{
if($this->request->is('post'))
{
$oConfig = new Config();
$oUploadDir = new Folder($oConfig::UPLOAD_DIRECTORY);
debug($oUploadDir);
$aFile = $this->request->data('submittedfile');
}
}
So despite my IDE even registering the class (and telling me I'm using it correctly) I get Class 'App\Library\Config' not found thrown in the browser.
I changed the name from Library to Berry (My first name).
Apparently you can't call it Library. Probably used somewhere else in Cake.
Related
I have controller name as 'CashFlowdata'. In controller I am having code that is :
namespace App\Modules\CashFlowdata\Controllers;
use App\Http\Controllers\Controller;
use App\Modules\CashFlowdata\Models\CashModel;
use App\Modules\CashFlowdata\Lcurd\CashFlowdataLcurd;
use Auth, Womp, Graphs, Projects, Input , Permissions, LcrudForm, LcrudTable, Redirect, Session, Meta;
class CashFlowdataController extends Controller
{
private $lcrud;
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct() {
$this->middleware('auth');
$this->lcrud = new CashFlowdataLcurd();
}
}
But in that I am getting error for
Class 'App\Modules\CashFlowdata\Lcurd\CashFlowdataLcurd' not found
But the file is there and that is with the same name.
If class and file have the same name (case sensitive), maybe you need a
composer dump-autoload
PS: Check 'lcurd' vs 'lcrud'
In Laravel I need to communicate to a 3rd party API. Thay have given me some PHP implementation (class) which I can use to connect and communicate with their API.
But when I try this as a class in a subfolder of the App folder and add this to my controller, I get a class not found error.
I have added a folder 'Qenner' (the provider of the API) in the App folder. And copied their classes in there.
In my controller I'm using these classes and add a code sample, like they send it to me.
Controller code (API-KEY is replaced with the actual key):
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Qenner\Search;
use QennerSearch\ServiceClient;
class TestController extends Controller
{
public function index() {
$search = new Search('https://search.qenner.com', 'API-KEY', true, 'nl-NL');
$response = $search->getCriteria([], ['Country'], []);
if (!$response->isError()) {
$criterionSets = $response->getCriterionSets();
$countryCriterionSet = criterionSets[0];
$countries = $countryCriterionSet->getCriteria();
$resultCount = $response->getResultCount();
}
dd($response);
}
Search.php in Qenner folder:
/**
* #file
* Contains QennerSearch\Search.
*/
namespace QennerSearch;
use QennerSearch\model\messages\CriterionTypesResponse;
use QennerSearch\model\messages\CriteriaRequest;
use QennerSearch\model\messages\CriteriaResponse;
use QennerSearch\model\messages\ErrorResponse;
use QennerSearch\model\messages\SearchRequest;
use QennerSearch\model\messages\SearchResponse;
use QennerSearch\model\messages\PriceRequest;
use QennerSearch\model\messages\PriceResponse;
use QennerSearch\model\messages\AccommodationInfoRequest;
use QennerSearch\model\messages\AccommodationInfoResponse;
use QennerSearch\model\messages\AutoCompleteRequest;
use QennerSearch\model\messages\AutoCompleteResponse;
/**
* Class Search, using ServiceClient to communicate, implementing the SearchInterface
*
* #package QennerSearch
*/
class Search extends ServiceClient implements SearchInterface {
.....
The folder has a ServiceClient.php
ServiceClient.php
/**
* #file
* Contains QennerSearch\Search.
*/
namespace QennerSearch;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
/**
* Class Search.
*
* #package QennerSearch
*/
class ServiceClient {
protected $http_client = null;
protected $engine_url = null;
protected $api_key = null;
protected $log_calls = false;
protected $locale = null;
protected $last_result_code = 0;
protected $last_error_body = null;
public function __construct($engine_url, $api_key, $log_calls = false, $locale = "nl-NL") {
$this->http_client = new Client();
$this->engine_url = $engine_url;
$this->api_key = $api_key;
$this->log_calls = $log_calls;
$this->locale = $locale;
I get this error:
Class 'QennerSearch\ServiceClient' not found
While I expected a dump of the output
Updated
After seeing your folder structure in the comments, I believe ServiceClient.php and Search.php, both are inside the folder: app\Qenner, hence inside those files:
wherever you are using: namespace QennerSearch;
you should use: namespace App\Qenner;
and then inside your controller, instead of using: use QennerSearch\ServiceClient;
use: namespace App\Qenner\ServiceClient
Namespaces are not like aliases, they need to reflect the position of the file itself if that makes sense.
Please give it a try and let me know if it works.
I'm using doctrine Doctrine MongoDB ODM 1.0.3. When trying to update document using doctrine I'm getting the following error:
Class XXX is not a valid document or mapped super class.
I have the following class for the document:
<?php
namespace Documents;
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
/**
* #ODM\Document(collection="posts")
*/
class Posts
{
/** #ODM\Id */
private $id;
/** #ODM\Field(type="string") */
private $title;
/** #ODM\EmbedMany(targetDocument="Comment") */
private $comments = array();
public function setTitle($title)
{
$this->title = $title;
}
public function getTitle()
{
return $this->title;
}
public function addComment($comment)
{
$this->comments[] = $comment;
}
public function getComments()
{
return $this->comments;
}
}
The following code is used to add new document:
$post = new \Documents\Posts();
$post->setTitle( $_POST['title'] );
$dm->persist($post);
$dm->flush();
Later I want to update the added document to add new comment for example. I use the following code:
$comment = new \Documents\Comment($_POST['comment_text']);
$dm->createQueryBuilder('Posts')
->update()
->field('comments')->push($comment)
->field('_id')->equals(new \MongoId($_POST['id']))
->getQuery()
->execute();
but getting the above mentioned error.
As you stated in your own answer you need to provide fully qualified name of class. Just wanted to add that better than to pass the string it is to use static class property like this instead: createQueryBuilder(\Documents\Posts::class); It works much better with IDEs (autocompletion, refactoring etc...)
For people getting this error in PHP 8 and above, check that you are not mixing annotations (e.g. /** #Entity */) and attributes (e.g. #[Entity]), and that you have indicated which method you are using in your config:
mappings:
App:
# pick one:
type: annotation
type: attribute
This always trips me up when I start a new project and the config defaults to annotations when I'm used to using attributes.
In case anyone else have a similar problem, you need to pass fully qualified class name to createQueryBuilder. My document classes are all inside Documents namespace so after passing it like this createQueryBuilder('\Documents\Posts') the problem is solved.
Based on the other varying answers here, it seems this error isn't super precise.
In my case the class was missing the EmbeddedDocument annotation.
namespace Foo;
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
/**
* #ODM\EmbeddedDocument
*/
class Bar { }
I am trying to resolve class via __construct using Laravel's bind() method.
Here what I do:
routes.php (of course I will move it away from here)
// Bindings
App::bind(
'License\Services\ModuleSelector\SelectorInterface',
'License\Services\ModuleSelector\ModuleSelector'
);
SelectorInterface.php - interface that I will expect in __construct method.
<?php namespace License\Services\ModuleSelector;
interface SelectorInterface {
/**
* Simply return query that will select needle module fields
*
* #return mixed
*/
public function make();
}
ModuleSelector.php - this is class that I want to resolve via Laravel's DI (see example below).
<?php namespace License\Services\ModuleSelector;
use License\Services\ModuleSelector\Selector;
class ModuleSelector extends Selector
{
/**
* Get module by it's code
*
* #return mixed
*/
public function find()
{
return $this->make()
->where('code', $module_code)
->first();
}
}
Module.php
<?php namespace License\Services\ModuleType;
use License\Services\ModuleType\TypeInterface;
use License\Services\ModuleSelector\SelectorInterface;
class Module
{
...
function __construct(SelectorInterface $selector)
{
$this->selector = $selector;
}
...
}
And the place when error occurs:
In my repo I have use License\Services\ModuleType\Module as ModuleService;.
Than there is method called find():
/**
* Find module by its code with all data (types, selected type)
* #return mixed
*/
public function find($module_code)
{
$module = new ModuleService;
// Get module id in order to use build in relations in framework
$module = $this->module->find($module_code);
...
}
So, in other words, I have 2 classes and one interface. What I am trying to do is:
1) Create Class1.php / Class2.php / Class2Interface.php.
2) In Class1.php in the __construct I specify __construct(Class2Interface $class2).
3) Instantiate Class2.
What I am doing wrong? Examples found here.
In this line:
$module = new ModuleService;
You are directly invoking the Module class and not passing in an instance of SelectorInterface.
For the IoC to work you bind and make classes using it. Try that line again with :
$module = App::make('License\Services\ModuleSelector\SelectorInterface');
An alernative is to inject it directly into your repos constructor, as long as the repo is created by the IoC container, your concrete will be automatically injected.
Nowhere do you have a class marked to actually "implement SelectorInterface".
Fatal error: Class 'Products\Summary\Html\Section' not found
I get the above error on the following code. I've verified that Summary\Html\Section() is indeed the namespace of the class I'm trying to access. I'm not entirely sure why this isn't working... any thoughts?
<?php
namespace Products;
use Products\Base as ProductBase;
use Products\Mapping as MappingInterface;
use Summary\Html;
class Product1 extends ProductBase implements MappingInterface {
/**
* Complete PDF mapping
*
* #return Array
*/
public function render() {
$preTable = new Summary\Html\Section();
$row = $preTable->addRow();
$row->addColumn()->setValue('Headline one')->addClass('first');
$row->addColumn()->setValue('Headline two')->addClass('first');
return $preTable;
}
My section class:
namespace Summary\Html;
use Summary\Html\Element;
use Summary\Html\Section\Row;
class Section extends Element {
Looks like it thinks Summary\Html is part of the Products namespace. Try this:
$preTable = new \Summary\Html\Section();