Related
I try to learn oop but in my first class it gives me this error.
Database class
<?php
namespace App;
class Database
{
...
}
in my functions.php
<?php
require 'helpers.php';
require 'connection.php';
use App\Database;
...
Class under the "app" folder and it's namespace is "App". Why I'm getting this error ?
You either need to include the file, or use an AutoLoader. AutoLoaders tell PHP where a class can be found, as PHP needs to know the file.
Autoloaders are fully explained in the PHP documentation:
https://secure.php.net/manual/en/language.oop5.autoload.php
Example from the mentioned documentation:
<?php
spl_autoload_register(function ($class_name) {
include $class_name . '.php';
});
$obj = new MyClass1();
$obj2 = new MyClass2();
?>
In this case spl_autoload_register is used to register the autoloader. The autoloader is a function which takes the class name, and includes the necessary class. For example you can use the autoloader function as used above, in which case the class name needs to be identical to the filename.
This is a quite simple example, but a more advanced autoloader could check if files exist, check multiple locations, etc...
Examples are mentioned in the comments on your original question.
note: You will find other sources mentioning the __autoload($class) function. This function does exactly the same, but will be removed from PHP in future updates. Therefore, you are better off using spl_autoload_register
Because I posted my Autoloader in the comments.
https://github.com/ArtisticPhoenix/MISC/blob/master/Autoloader.php
You can find the code at the bottom of this post:
The basic usage is as follows:
require_once 'Autoloader.php';
AutoLoader::getInstance()->regesterPath('\\', __DIR__);
This assumes it's in the directory that is the root of you namespace. So if you have a class.
namespace App;
class Database{ ... }
And this class is in
www
|- Autoloader.php
|- App
| --Database.php
Then it will look for __DIR__ + Namespace or __DIR__/APP/. You can register paths because if you have this setup.
www
|- Autoloader.php
|- includes
|-- App
| ---Database.php
Where the class is located in includes/App and Autoloader is in / the root folder you can do it this way.
require_once 'Autoloader.php';
AutoLoader::getInstance()->regesterPath('\\', __DIR__.'/includes/');
Also if you have it setup like this.
www
|- Autoloader.php
|- includes
| --Database.php
Where there is no actual App folder then you can do it like this.
require_once 'Autoloader.php';
AutoLoader::getInstance()->regesterPath('\\App\\', __DIR__.'/includes/');
Or any combination of the above.
It will account for the differences between \\App. App and \\App\\ for the most part. But you can also turn on debugging with this.
require_once 'Autoloader.php';
$AutoLoader = AutoLoader::getInstance();
$AutoLoader->setDebug(true);
$AutoLoader>regesterPath('\\App\\', __DIR__.'/includes/');
And it will spit out a bunch of stuff telling you where it is looking. You may have to use <pre> to keep the whitespace format, if your working in HTML. Conveniently you can also turn off Debugging, because you may be autoloading a bunch of classes.
$AutoLoader->setDebug(false);
You can also assign multiple paths, and give them a priority and it will look in them in the order of the priority. But that is not really important in this case.
So for example:
I have a folder
www
|-MISC
|--index.php
|--Autoloader.php
|---IMAP
|----GmailClient.php
Which is also in the same Git Repo. It has the namespace of Lib\Email\IMAP of which only the IMAP exists.
And to load It if I do this in index.php, which is inside the MISC file and at the same level as the AutoLoader.php file:
//include the Autoloader
require_once __DIR__.'/Autoloader.php';
//get an instance of it (Singleton pattern)
$Autoloader = Autoloader::getInstance();
//regester a namespace, path pair
$Autoloader->regesterPath('Lib\Email', __DIR__.'/IMAP/');
//preserve whitespace
echo "<pre>";
//turn on debugging before a problem class
$Autoloader->setDebug(true);
//Attempt to load the class as normal
$G = new GmailClient($hostname, $username, $password);
//turn off debugging after trying to load a problem class.
$AutoLoader->setDebug(false);
This is what it Outputs for debugging
================================= Autoloader::debugMode ==================================
Autoloader::splAutoload Lib\Email\IMAP\GmailClient
Checking class: GmailClient
Checking namespace: Lib/Email/IMAP
checking pathname:C:/Server/www/MISC/IMAP/IMAP/GmailClient.php
==========================================================================================
Right away we can see C:/Server/www/MISC/IMAP/IMAP/GmailClient.php That IMAP is in there 2x. This is because I included that in the path, So it starts looking in C:/Server/www/MISC/IMAP/ and then adds the namespace that wasn't given in the namespace arg IMAP from Lib/Email/IMAP. We gave it Lib/Email as the first argument. So essentially, because this was part of the path it's already in that folder when it looks for that.
So If I just remove that IMAP from the path:
$Autoloader->regesterPath('Lib\Email', __DIR__);
It will output this:
================================= Autoloader::debugMode ==================================
Autoloader::splAutoload Lib\Email\IMAP\GmailClient
Checking class: GmailClient
Checking namespace: Lib/Email/IMAP
checking pathname:C:/Server/www/MISC/IMAP/GmailClient.php
Found: C:/Server/www/MISC/IMAP/GmailClient.php
==========================================================================================
With the most important line being this
Found: C:/Server/www/MISC/IMAP/GmailClient.php
Which obviously means that it found the class file and loaded it.
Hope that makes sense.
Following is the full code for the autoloader, that way the answer wont break if anything changes with the Repo I linked.
<?php
/**
*
* (c) 2016 ArtisticPhoenix
*
* For license information please view the LICENSE file included with this source code. GPL-3
*
* PSR4 compatible Autoloader
*
* #author ArtisticPhoenix
* #see http://www.php-fig.org/psr/psr-4/
*
* #example
* $Autoloader = Autoloader::getInstance();
* //looks in includes for folder named /includes/Lib/Auth/User/
* $Autoloader->regesterPath('Lib\\Auth\\User', __DIR__.'/includes/');
*
*/
final class Autoloader
{
/**
*
* #var int
*/
const DEFAULT_PRIORITY = 10;
/**
* namespace / class path storage
* #var array
*/
private $paths = array();
/**
* cashe the loaded files
* #var array
*/
private $files = array();
/**
* namespace / class path storage
* #var array
*/
private $debugMode = false;
/**
*
* #var Self
*/
private static $instance;
/**
* No public construction allowed - Singleton
*/
private function __construct($throw, $prepend)
{
spl_autoload_register(array( $this,'splAutoload'), $throw, $prepend);
}
/**
* No cloning of allowed
*/
private function __clone()
{
}
/**
*
* Get an instance of the Autoloader Singleton
* #param boolean $throw
* #param boolean $prepend
* #return self
*/
public static function getInstance($throw = false, $prepend = false)
{
if (!self::$instance) {
self::$instance = new self($throw, $prepend);
}
return self::$instance;
}
/**
* set debug output
* #param boolean $debug
* #return self
*/
public function setDebug($debug = false)
{
$this->debugMode = $debug;
return $this;
}
/**
* Autoload
* #param string $class
*/
public function splAutoload($class)
{
$this->debugMode('_START_');
$this->debugMode(__METHOD__.' '.$class);
//keep the orignal class name
$_class = str_replace('\\', '/', $class);
$namespace = '';
if (false !== ($pos = strrpos($_class, '/'))) {
$namespace = substr($_class, 0, ($pos));
$_class = substr($_class, ($pos + 1));
}
//replace _ in class name only
if (false !== ($pos = strrpos($_class, '/'))) {
if (strlen($namespace)) {
$namespace .= '/'.substr($_class, 0, ($pos));
} else {
$namespace = substr($_class, 0, ($pos));
}
$_class = substr($_class, ($pos + 1));
}
$this->debugMode("Checking class: $_class");
$this->debugMode("Checking namespace: $namespace");
do {
if (isset($this->paths[ $namespace ])) {
foreach ($this->paths[ $namespace ] as $registered) {
$filepath = $registered['path'] . $_class . '.php';
$this->debugMode("checking pathname:{$filepath}");
if (file_exists($filepath)) {
$this->debugMode("Found: $filepath");
$this->debugMode('_END_');
require_once $filepath;
$this->files[$class] = $filepath;
}
}
}
if (strlen($namespace) == 0) {
//if the namespace is empty and we couldn't find the class we are done.
break;
}
if (false !== ($pos = strrpos($namespace, '/'))) {
$_class = substr($namespace, ($pos + 1)) . '/' . $_class;
$namespace = substr($namespace, 0, ($pos));
} else {
$_class = (strlen($namespace) ? $namespace : '') . '/' . $_class;
$namespace = '';
}
} while (true);
$this->debugMode('_END_');
}
/**
* get the paths regestered for a namespace, leave null go get all paths
* #param string $namespace
* #return array or false on falure
*/
public function getRegisteredPaths($namespace = null)
{
if (is_null($namespace)) {
return $this->paths;
} else {
return (isset($this->paths[$namespace])) ? array($namespace => $this->paths[$namespace]) : false;
}
}
/**
*
* #param string $namespace
* #param string $path
* #param int $priority
* #return self
*/
public function regesterPath($namespace, $path, $priority = self::DEFAULT_PRIORITY)
{
$namespace = str_replace('\\', '/', $namespace); //convert to directory seperator
$path = ($this->normalizePath($path));
$this->paths[$namespace][sha1($path)] = array(
'path' => $path,
'priority' => $priority
);
$this->sortByPriority($namespace);
return $this;
}
/**
* un-regester a path
* #param string $namespace
* #param string $path
*/
public function unloadPath($namespace, $path = null)
{
if ($path) {
$path = $this->normalizePath($path);
unset($this->paths[$namespace][sha1($path)]);
} else {
unset($this->paths[$namespace]);
}
}
/**
* check if a namespace is regestered
* #param string $namespace
* #param string $path
* #return bool
*/
public function isRegistered($namespace, $path = null)
{
if ($path) {
$path = $this->normalizePath($path);
return isset($this->paths[$namespace][sha1($path)]) ? true : false;
} else {
return isset($this->paths[$namespace]) ? true : false;
}
}
/**
* get the file pathname of a loaded class
* #param string $class
* #return mixed
*/
public function getLoadedFile($class = null)
{
if (!$class) {
return $this->files;
}
if (isset($this->files[$class])) {
return $this->files[$class];
}
}
/**
* output debug message
* #param string $message
*/
protected function debugMode($message)
{
if (!$this->debugMode) {
return;
}
switch ($message) {
case '_START_':
echo str_pad("= ".__METHOD__." =", 90, "=", STR_PAD_BOTH) . PHP_EOL;
break;
case '_END_':
echo str_pad("", 90, "=", STR_PAD_BOTH) . PHP_EOL . PHP_EOL;
break;
default:
echo $message . PHP_EOL;
}
}
/**
* sort namespaces by priority
* #param string $namespace
*/
protected function sortByPriority($namespace)
{
uasort($this->paths[$namespace], function ($a, $b) {
return ($a['priority'] > $b['priority']) ? true : false;
});
}
/**
* convert a path to unix seperators and make sure it has a trailing slash
* #param string $path
* #return string
*/
protected function normalizePath($path)
{
if (false !== strpos($path, '\\')) {
$path = str_replace("\\", "/", $path);
}
return rtrim($path, '/') . '/';
}
}
P.S. the GmailClient class I used in this example, I wrote to parse incoming Emails in a Gmail account. It's not 100% fleshed out as we needed it for a specific purpose. But it is in the same GitHub repository.
I want to validate the object properties. Because we do not know PHP OOP more, we chose this way:
First create Validator:
namespace Validator;
/**
* Class ObjectPropertyValidator - Validate object, test if have all property
* #package Validator
*/
class ObjectPropertyValidator {
/**
* #param object $object
*
* #throws ValidatorException
*/
public static function validate($object) {
$reflectionClass = new \ReflectionClass(get_called_class());
foreach ($reflectionClass->getProperties() as $property) {
$name = $property->name;
if (!property_exists($object, $name)) {
throw new ValidatorException('Object not have property ' . $name, 0);
}
new PropertyValidator($property->getDocComment(), $object->$name, $name);
}
}
}
Next I am create Property Validator (I do not have all types validating):
namespace Validator;
/**
* Class PropertyValidator - Parse PHPDOC to pieces and validate input property
* #package Validator
*/
class PropertyValidator {
const DOC_PATTERN = '/#var\s+(?<object>\\\?)(?<type>[0-9A-Za-z\\\]+)(?<array>\[?\]?)/';
const DOC_IS_ARRAY = '[]';
const DOC_IS_OBJECT = '\\';
/** #var bool */
public $is_Array = false;
/** #var bool */
public $is_Object = false;
/** #var string */
public $type = '';
/**
* PropertyValidator constructor.
*
* Where make validating over PHPDOC over $property
*
* #param string $doc PHPDOC
* #param mixed $property Validating Property
* #param string $name Name of property
*/
public function __construct($doc, $property, $name) {
$this->analyzePHPDOC($doc);
$this->validate($property, $name);
}
/**
* #param string $doc
*/
private function analyzePHPDOC($doc) {
if (preg_match(self::DOC_PATTERN, $doc, $matches)) {
$this->is_Array = $matches['array'] === self::DOC_IS_ARRAY;
$this->type = $matches['object'] . $matches['type'];
$this->is_Object = $matches['object'] === self::DOC_IS_OBJECT;
}
}
/**
* #param object $property
* #param string $name
*
* #throws ValidatorException
*/
private function validate($property, $name) {
if ($this->is_Array) {
if (!is_array($property)) {
throw new ValidatorException('Object not have property ' . $name . ' type array', 0);
}
if ($this->is_Object) {
$validator = new $this->type();
foreach ($property as $subobject) {
/** #var ObjectPropertyValidator $validator */
$validator::validate($subobject);
}
}
} else {
if ($this->is_Object) {
$validator = new $this->type();
/** #var ObjectPropertyValidator $validator */
$validator::validate($property);
} else {
switch ($this->type) {
case 'string':
if (!is_string($property)) {
throw new ValidatorException('Property ' . $name . ' is not string', 0);
}
break;
case 'int':
case 'integer':
if (!is_numeric($property)) {
throw new ValidatorException('Property ' . $name . ' is not numeric', 0);
}
break;
}
}
}
}
}
Here I have a skeleton classes for validation (in separate files):
namespace Object;
use Validator\ObjectPropertyValidator;
class SkeletonForValidatingA extends ObjectPropertyValidator {
/** #var string */
public $someProperty;
/** #var \Object\SkeletonForValidatingB[] */
public $somePropertyArray;
}
namespace Object;
use Validator\ObjectPropertyValidator;
class SkeletonForValidatingB extends ObjectPropertyValidator {
/** #var int*/
public $someProperty;
}
And last how to I using all:
$parameters = '{"someProperty":"some text", "somePropertyArray":[{"someProperty":1}]}';
$parameters = Zend_Json::decode($parameters, false);
SkeletonForValidatingA::validate($parameters);
If anyone has any idea how to do it better, please send a tip!
Thank you all
I'm trying to create two custom providers, one for PDF and another one for ZIP files.
This is my code.
services.yml
parameters:
application_sonata_media.zip_class: Application\Sonata\MediaBundle\Provider\ZipProvider
services:
sonata.media.provider.zip:
class: %application_sonata_media.zip_class%
tags:
- { name: sonata.media.provider }
arguments:
- sonata.media.provider.zip
- #sonata.media.filesystem.local
- #sonata.media.cdn.server
- #sonata.media.generator.default
- #sonata.media.thumbnail.format
- ['zip']
- ['application/zip']
sonata_media.yml
sonata_media:
contexts:
eag_zip:
download:
strategy: sonata.media.security.public_strategy
mode: http
providers:
- sonata.media.provider.zip
formats:
reference: { quality: 100 }
ZipProvider.php
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
namespace Application\Sonata\MediaBundle\Provider;
use Sonata\MediaBundle\Provider\BaseProvider;
use Gaufrette\Filesystem;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Validator\ErrorElement;
use Sonata\CoreBundle\Model\Metadata;
use Sonata\MediaBundle\CDN\CDNInterface;
use Sonata\MediaBundle\Generator\GeneratorInterface;
use Sonata\MediaBundle\Metadata\MetadataBuilderInterface;
use Sonata\MediaBundle\Model\MediaInterface;
use Sonata\MediaBundle\Thumbnail\ThumbnailInterface;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\NotNull;
/**
* Description of ZipProvider
*
* #author Juanjo GarcĂa <juanjogarcia#editartgroup.com>
*/
class ZipProvider extends BaseProvider {
protected $allowedExtensions;
protected $allowedMimeTypes;
protected $metadata;
/**
* #param string $name
* #param \Gaufrette\Filesystem $filesystem
* #param \Sonata\MediaBundle\CDN\CDNInterface $cdn
* #param \Sonata\MediaBundle\Generator\GeneratorInterface $pathGenerator
* #param \Sonata\MediaBundle\Thumbnail\ThumbnailInterface $thumbnail
* #param array $allowedExtensions
* #param array $allowedMimeTypes
* #param \Sonata\MediaBundle\Metadata\MetadataBuilderInterface $metadata
*/
public function __construct($name, Filesystem $filesystem, CDNInterface $cdn, GeneratorInterface $pathGenerator, ThumbnailInterface $thumbnail, array $allowedExtensions = array(), array $allowedMimeTypes = array(), MetadataBuilderInterface $metadata = null)
{
parent::__construct($name, $filesystem, $cdn, $pathGenerator, $thumbnail);
$this->allowedExtensions = $allowedExtensions;
$this->allowedMimeTypes = $allowedMimeTypes;
$this->metadata = $metadata;
}
/**
* {#inheritdoc}
*/
public function getProviderMetadata()
{
return new Metadata($this->getName(), $this->getName().'.description', false, 'SonataMediaBundle', array('class' => 'fa fa-file-text-o'));
}
/**
* {#inheritdoc}
*/
public function getReferenceImage(MediaInterface $media)
{
return sprintf('%s/%s',
$this->generatePath($media),
$media->getProviderReference()
);
}
/**
* {#inheritdoc}
*/
public function getReferenceFile(MediaInterface $media)
{
return $this->getFilesystem()->get($this->getReferenceImage($media), true);
}
/**
* {#inheritdoc}
*/
public function buildEditForm(FormMapper $formMapper)
{
$formMapper->add('name');
$formMapper->add('enabled', null, array('required' => false));
$formMapper->add('authorName');
$formMapper->add('cdnIsFlushable');
$formMapper->add('description');
$formMapper->add('copyright');
$formMapper->add('binaryContent', 'file', array('required' => false));
}
/**
* {#inheritdoc}
*/
public function buildCreateForm(FormMapper $formMapper)
{
$formMapper->add('binaryContent', 'file', array(
'constraints' => array(
new NotBlank(),
new NotNull(),
),
));
}
/**
* {#inheritdoc}
*/
public function buildMediaType(FormBuilder $formBuilder)
{
$formBuilder->add('binaryContent', 'file');
}
/**
* {#inheritdoc}
*/
public function postPersist(MediaInterface $media)
{
if ($media->getBinaryContent() === null) {
return;
}
$this->setFileContents($media);
$this->generateThumbnails($media);
}
/**
* {#inheritdoc}
*/
public function postUpdate(MediaInterface $media)
{
if (!$media->getBinaryContent() instanceof \SplFileInfo) {
return;
}
// Delete the current file from the FS
$oldMedia = clone $media;
$oldMedia->setProviderReference($media->getPreviousProviderReference());
$path = $this->getReferenceImage($oldMedia);
if ($this->getFilesystem()->has($path)) {
$this->getFilesystem()->delete($path);
}
$this->fixBinaryContent($media);
$this->setFileContents($media);
$this->generateThumbnails($media);
}
/**
* #throws \RuntimeException
*
* #param \Sonata\MediaBundle\Model\MediaInterface $media
*
* #return
*/
protected function fixBinaryContent(MediaInterface $media)
{
if ($media->getBinaryContent() === null) {
return;
}
// if the binary content is a filename => convert to a valid File
if (!$media->getBinaryContent() instanceof File) {
if (!is_file($media->getBinaryContent())) {
throw new \RuntimeException('The file does not exist : '.$media->getBinaryContent());
}
$binaryContent = new File($media->getBinaryContent());
$media->setBinaryContent($binaryContent);
}
}
/**
* #throws \RuntimeException
*
* #param \Sonata\MediaBundle\Model\MediaInterface $media
*/
protected function fixFilename(MediaInterface $media)
{
if ($media->getBinaryContent() instanceof UploadedFile) {
$media->setName($media->getName() ?: $media->getBinaryContent()->getClientOriginalName());
$media->setMetadataValue('filename', $media->getBinaryContent()->getClientOriginalName());
} elseif ($media->getBinaryContent() instanceof File) {
$media->setName($media->getName() ?: $media->getBinaryContent()->getBasename());
$media->setMetadataValue('filename', $media->getBinaryContent()->getBasename());
}
// this is the original name
if (!$media->getName()) {
throw new \RuntimeException('Please define a valid media\'s name');
}
}
/**
* {#inheritdoc}
*/
protected function doTransform(MediaInterface $media)
{
$this->fixBinaryContent($media);
$this->fixFilename($media);
// this is the name used to store the file
if (!$media->getProviderReference()) {
$media->setProviderReference($this->generateReferenceName($media));
}
if ($media->getBinaryContent()) {
$media->setContentType($media->getBinaryContent()->getMimeType());
$media->setSize($media->getBinaryContent()->getSize());
}
$media->setProviderStatus(MediaInterface::STATUS_OK);
}
/**
* {#inheritdoc}
*/
public function updateMetadata(MediaInterface $media, $force = true)
{
// this is now optimized at all!!!
$path = tempnam(sys_get_temp_dir(), 'sonata_update_metadata');
$fileObject = new \SplFileObject($path, 'w');
$fileObject->fwrite($this->getReferenceFile($media)->getContent());
$media->setSize($fileObject->getSize());
}
/**
* {#inheritdoc}
*/
public function generatePublicUrl(MediaInterface $media, $format)
{
if ($format == 'reference') {
$path = $this->getReferenceImage($media);
} else {
// #todo: fix the asset path
$path = sprintf('sonatamedia/files/%s/file.png', $format);
}
return $this->getCdn()->getPath($path, $media->getCdnIsFlushable());
}
/**
* {#inheritdoc}
*/
public function getHelperProperties(MediaInterface $media, $format, $options = array())
{
return array_merge(array(
'title' => $media->getName(),
'thumbnail' => $this->getReferenceImage($media),
'file' => $this->getReferenceImage($media),
), $options);
}
/**
* {#inheritdoc}
*/
public function generatePrivateUrl(MediaInterface $media, $format)
{
if ($format == 'reference') {
return $this->getReferenceImage($media);
}
return false;
}
/**
* Set the file contents for an image.
*
* #param \Sonata\MediaBundle\Model\MediaInterface $media
* #param string $contents path to contents, defaults to MediaInterface BinaryContent
*/
protected function setFileContents(MediaInterface $media, $contents = null)
{
$file = $this->getFilesystem()->get(sprintf('%s/%s', $this->generatePath($media), $media->getProviderReference()), true);
if (!$contents) {
$contents = $media->getBinaryContent()->getRealPath();
}
$metadata = $this->metadata ? $this->metadata->get($media, $file->getName()) : array();
$file->setContent(file_get_contents($contents), $metadata);
}
/**
* #param \Sonata\MediaBundle\Model\MediaInterface $media
*
* #return string
*/
protected function generateReferenceName(MediaInterface $media)
{
return sha1($media->getName().rand(11111, 99999)).'.'.$media->getBinaryContent()->guessExtension();
}
/**
* {#inheritdoc}
*/
public function getDownloadResponse(MediaInterface $media, $format, $mode, array $headers = array())
{
// build the default headers
$headers = array_merge(array(
'Content-Type' => $media->getContentType(),
'Content-Disposition' => sprintf('attachment; filename="%s"', $media->getMetadataValue('filename')),
), $headers);
if (!in_array($mode, array('http', 'X-Sendfile', 'X-Accel-Redirect'))) {
throw new \RuntimeException('Invalid mode provided');
}
if ($mode == 'http') {
if ($format == 'reference') {
$file = $this->getReferenceFile($media);
} else {
$file = $this->getFilesystem()->get($this->generatePrivateUrl($media, $format));
}
return new StreamedResponse(function () use ($file) {
echo $file->getContent();
}, 200, $headers);
}
if (!$this->getFilesystem()->getAdapter() instanceof \Sonata\MediaBundle\Filesystem\Local) {
throw new \RuntimeException('Cannot use X-Sendfile or X-Accel-Redirect with non \Sonata\MediaBundle\Filesystem\Local');
}
$filename = sprintf('%s/%s',
$this->getFilesystem()->getAdapter()->getDirectory(),
$this->generatePrivateUrl($media, $format)
);
return new BinaryFileResponse($filename, 200, $headers);
}
/**
* {#inheritdoc}
*/
public function validate(ErrorElement $errorElement, MediaInterface $media)
{
if (!$media->getBinaryContent() instanceof \SplFileInfo) {
return;
}
if ($media->getBinaryContent() instanceof UploadedFile) {
$fileName = $media->getBinaryContent()->getClientOriginalName();
} elseif ($media->getBinaryContent() instanceof File) {
$fileName = $media->getBinaryContent()->getFilename();
} else {
throw new \RuntimeException(sprintf('Invalid binary content type: %s', get_class($media->getBinaryContent())));
}
if (!in_array(strtolower(pathinfo($fileName, PATHINFO_EXTENSION)), $this->allowedExtensions)) {
$errorElement
->with('binaryContent')
->addViolation('Invalid extensions')
->end();
}
if (!in_array($media->getBinaryContent()->getMimeType(), $this->allowedMimeTypes)) {
$errorElement
->with('binaryContent')
->addViolation('Invalid mime type : '.$media->getBinaryContent()->getMimeType())
->end();
}
}
}
When I push create and edit button, the file pass the validation, save in DDBB and file in server, but in URL /admin/sonata/media/media/233/edit?provider=sonata.media.provider.zip&context=eag_zip I get this Error message:
Unable to find template "" in SonataMediaBundle:MediaAdmin:edit.html.twig at line 48.
Trying to go to /admin/sonata/media/media/list?provider=sonata.media.provider.zip&context=eag_zip or /admin/sonata/media/media/list?context=eag_zip
Unable to find template "" in SonataMediaBundle:MediaAdmin:inner_row_media.html.twig at line 19.
I don't know to solve it.
any help would be welcome
thanks a lot
Solved here
services:
sonata.media.provider.zip:
class: %application_sonata_media.zip_class%
tags:
- { name: sonata.media.provider }
arguments:
- sonata.media.provider.zip
- #sonata.media.filesystem.local
- #sonata.media.cdn.server
- #sonata.media.generator.default
- #sonata.media.thumbnail.format
- ['zip']
- ['application/zip']
calls:
- [ setTemplates, [{helper_view:SonataMediaBundle:Provider:view_image.html.twig,helper_thumbnail:SonataMediaBundle:Provider:thumbnail.html.twig}]]
Hi
Can anyone tell me how to use openinviter script in zend framework
I have used Open Invitor in one of my projects by following a tutorials. Unfortunately, I couldn't find out the link. Here are the main steps:
(a) Create a custom library. To do this, create a folder inside library (library/openinvitor)
(b) Install the Open Invitor Package inside this library (ie library/openinvitor/install.php). I did this by commenting index & htaccess during the installation.
(c) Register new library in the Boot Strap. (Copy the line needed for the Open Invitor Loading)
protected function _initAutoload ()
{
// Add autoloader empty namespace
$autoLoader = Zend_Loader_Autoloader::getInstance();
$autoLoader->registerNamespace('openinviter_');
$resourceLoader = new Zend_Loader_Autoloader_Resource(array('basePath' => APPLICATION_PATH , 'namespace' => '' , 'resourceTypes' => array('form' => array('path' => 'forms/' , 'namespace' => 'Form_') , 'model' => array('path' => 'models/' , 'namespace' => 'Model_'))));
// Return it so that it can be stored by the bootstrap
return $autoLoader;
}
(d) The file name of the library file is: Service.php Also note the name of the class in the step (e)
(e) The content of the Service file is:
<?php
require_once 'openinviter.php';
/**
* This class is the connection between OpenInviter service and Zend Framework.
* The class is implemented only for extracting contacts.
*
* #tutorial
*
* $inviter = new OpenInviter_Service();
*
* p($inviter->getPlugins());// get all services
* p($inviter->getPlugins('email'));// get all services
* p($inviter->getPlugins('email', 'gmail'));// get gmail plugin properties
* p($inviter->getPlugins('email', 'gmail', 'version'));// get gmail plugin version
*
* // get contacts
* p($inviter->getContacts('me#example.com', 'mypass', 'example'));
*
*
* #author stoil
* #link http://openinviter.com/
* #uses OpenInviter 1.7.6
*
*/
class openinviter_Service
{
const PATH_PLUGINS = 'plugins/';
protected $_messages = array();
protected $_plugins;
protected $_openInviter;
/*~~~~~~~~~~ private methods ~~~~~~~~~~*/
private function _loadPlugins()
{
if($this->_plugins === null) {
$this->_plugins = $this->getOpenInviter()->getPlugins(false);
}
}
/*~~~~~~~~~~ protected methods ~~~~~~~~~~*/
protected function _addMessage($code, $message, $type = 'error')
{
$this->_messages[$type][$code] = $message;
}
protected function _initAutoload()
{
set_include_path(
dirname(realpath(__FILE__)) . DIRECTORY_SEPARATOR . self::PATH_PLUGINS.
PATH_SEPARATOR.
get_include_path()
);
}
/*~~~~~~~~~~ constructor ~~~~~~~~~~*/
public function __construct()
{
$this->_initAutoload();
$this->_openInviter = new openinviter();
$this->_loadPlugins();
}
/*~~~~~~~~~~ public methods ~~~~~~~~~~*/
/**
* Update plugins
*/
public function updatePlugins()
{
$this->_plugins = $this->getOpenInviter()->getPlugins(true);
}
/**
* Get plugin(s), provider(s) or provider details
* #param $type
* #param $provider
* #param $detail
* #return unknown_type
*/
public function getPlugins($type = null, $provider = null, $detail = null)
{
if ($type !== null) {
if ($provider !== null) {
if ($detail !== null) {
return $this->_plugins[$type][$provider][$detail];
} else {
return $this->_plugins[$type][$provider];
}
} else {
return $this->_plugins[$type];
}
} else {
return $this->_plugins;
}
}
/**
* #return openinviter
*/
protected function getOpenInviter()
{
return $this->_openInviter;
}
/**
* Get system messages
* #param string $type
* #return array
*/
public function getMessages($type = null)
{
if($type !== null) {
return $this->_messages[$type];
} else {
return $this->_messages;
}
}
/**
* Get email clients
* #param string $email
* #param string $password
* #param string $provider
* #return array
*/
public function getContacts($email, $password, $provider)
{
$contacts = array();
$this->getOpenInviter()->startPlugin($provider);
$internalError = $this->getOpenInviter()->getInternalError();
if ($internalError) {
$this->_addMessage('inviter', $internalError);
} elseif (! $this->getOpenInviter()->login($email, $password)) {
$internalError = $this->getOpenInviter()->getInternalError();
$this->_addMessage(
'login',
($internalError
? $internalError
: 'Login failed. Please check the email and password you have provided and try again later !'
)
);
} elseif (false === $contacts = $this->getOpenInviter()->getMyContacts()) {
$this->_addMessage('contacts', 'Unable to get contacts');
}
return $contacts;
}
}
(f) Then in the desired controller/function, create an object of the Open Invitor librray and access any functions.
$inviter = new openinviter_Service(); // Create the Object of Opne Invitor
$plugins = $inviter->getPlugins('email'); // Read all Available Plugins.
Do anyone know why this occurs?
as far I can get, the child class method is declared in the same way as parent's.
Thanks!
here is my kernel code:
<?php
require_once __DIR__.'/../src/autoload.php';
use Symfony\Framework\Kernel;
use Symfony\Components\DependencyInjection\Loader\YamlFileLoader as ContainerLoader;
use Symfony\Components\Routing\Loader\YamlFileLoader as RoutingLoader;
use Symfony\Framework\KernelBundle;
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
use Symfony\Bundle\ZendBundle\ZendBundle;
use Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle;
use Symfony\Bundle\DoctrineBundle\DoctrineBundle;
use Symfony\Bundle\DoctrineMigrationsBundle\DoctrineMigrationsBundle;
use Symfony\Bundle\DoctrineMongoDBBundle\DoctrineMongoDBBundle;
use Symfony\Bundle\PropelBundle\PropelBundle;
use Symfony\Bundle\TwigBundle\TwigBundle;
use Application\UfaraBundle\UfaraBundle;
class UfaraKernel extends Kernel {
public function registerRootDir() {
return __DIR__;
}
public function registerBundles() {
$bundles = array(
new KernelBundle(),
new FrameworkBundle(),
new ZendBundle(),
new SwiftmailerBundle(),
new DoctrineBundle(),
//new DoctrineMigrationsBundle(),
//new DoctrineMongoDBBundle(),
//new PropelBundle(),
//new TwigBundle(),
new UfaraBundle(),
);
if ($this->isDebug()) {
}
return $bundles;
}
public function registerBundleDirs() {
$bundles = array(
'Application' => __DIR__.'/../src/Application',
'Bundle' => __DIR__.'/../src/Bundle',
'Symfony\\Framework' => __DIR__.'/../src/vendor/symfony/src/Symfony/Framework',
'Symfony\\Bundle' => __DIR__.'/../src/vendor/symfony/src/Symfony/Bundle',
);
return $bundles;
}
public function registerContainerConfiguration(LoaderInterface $loader) {
return $loader->load(__DIR__.'/config/config_'.$this->getEnvironment().'.yml');
}
public function registerRoutes() {
$loader = new RoutingLoader($this->getBundleDirs());
return $loader->load(__DIR__.'/config/routing.yml');
}
}
here is the parent class code:
<?php
namespace Symfony\Framework;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
use Symfony\Component\DependencyInjection\Resource\FileResource;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
use Symfony\Component\DependencyInjection\Loader\DelegatingLoader;
use Symfony\Component\DependencyInjection\Loader\LoaderResolver;
use Symfony\Component\DependencyInjection\Loader\LoaderInterface;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\DependencyInjection\Loader\IniFileLoader;
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
use Symfony\Component\DependencyInjection\Loader\ClosureLoader;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Framework\ClassCollectionLoader;
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien.potencier#symfony-project.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* The Kernel is the heart of the Symfony system. It manages an environment
* that can host bundles.
*
* #author Fabien Potencier <fabien.potencier#symfony-project.org>
*/
abstract class Kernel implements HttpKernelInterface, \Serializable
{
protected $bundles;
protected $bundleDirs;
protected $container;
protected $rootDir;
protected $environment;
protected $debug;
protected $booted;
protected $name;
protected $startTime;
protected $request;
const VERSION = '2.0.0-DEV';
/**
* Constructor.
*
* #param string $environment The environment
* #param Boolean $debug Whether to enable debugging or not
*/
public function __construct($environment, $debug)
{
$this->environment = $environment;
$this->debug = (Boolean) $debug;
$this->booted = false;
$this->rootDir = realpath($this->registerRootDir());
$this->name = basename($this->rootDir);
if ($this->debug) {
ini_set('display_errors', 1);
error_reporting(-1);
$this->startTime = microtime(true);
} else {
ini_set('display_errors', 0);
}
}
public function __clone()
{
if ($this->debug) {
$this->startTime = microtime(true);
}
$this->booted = false;
$this->container = null;
$this->request = null;
}
abstract public function registerRootDir();
abstract public function registerBundles();
abstract public function registerBundleDirs();
abstract public function registerContainerConfiguration(LoaderInterface $loader);
/**
* Checks whether the current kernel has been booted or not.
*
* #return boolean $booted
*/
public function isBooted()
{
return $this->booted;
}
/**
* Boots the current kernel.
*
* This method boots the bundles, which MUST set
* the DI container.
*
* #throws \LogicException When the Kernel is already booted
*/
public function boot()
{
if (true === $this->booted) {
throw new \LogicException('The kernel is already booted.');
}
if (!$this->isDebug()) {
require_once __DIR__.'/bootstrap.php';
}
$this->bundles = $this->registerBundles();
$this->bundleDirs = $this->registerBundleDirs();
$this->container = $this->initializeContainer();
// load core classes
ClassCollectionLoader::load(
$this->container->getParameter('kernel.compiled_classes'),
$this->container->getParameter('kernel.cache_dir'),
'classes',
$this->container->getParameter('kernel.debug'),
true
);
foreach ($this->bundles as $bundle) {
$bundle->setContainer($this->container);
$bundle->boot();
}
$this->booted = true;
}
/**
* Shutdowns the kernel.
*
* This method is mainly useful when doing functional testing.
*/
public function shutdown()
{
$this->booted = false;
foreach ($this->bundles as $bundle) {
$bundle->shutdown();
$bundle->setContainer(null);
}
$this->container = null;
}
/**
* Reboots the kernel.
*
* This method is mainly useful when doing functional testing.
*
* It is a shortcut for the call to shutdown() and boot().
*/
public function reboot()
{
$this->shutdown();
$this->boot();
}
/**
* Gets the Request instance associated with the master request.
*
* #return Request A Request instance
*/
public function getRequest()
{
return $this->request;
}
/**
* Handles a request to convert it to a response by calling the HttpKernel service.
*
* #param Request $request A Request instance
* #param integer $type The type of the request (one of HttpKernelInterface::MASTER_REQUEST or HttpKernelInterface::SUB_REQUEST)
* #param Boolean $raw Whether to catch exceptions or not
*
* #return Response $response A Response instance
*/
public function handle(Request $request = null, $type = HttpKernelInterface::MASTER_REQUEST, $raw = false)
{
if (false === $this->booted) {
$this->boot();
}
if (null === $request) {
$request = $this->container->get('request');
} else {
$this->container->set('request', $request);
}
if (HttpKernelInterface::MASTER_REQUEST === $type) {
$this->request = $request;
}
$response = $this->container->getHttpKernelService()->handle($request, $type, $raw);
$this->container->set('request', $this->request);
return $response;
}
/**
* Gets the directories where bundles can be stored.
*
* #return array An array of directories where bundles can be stored
*/
public function getBundleDirs()
{
return $this->bundleDirs;
}
/**
* Gets the registered bundle names.
*
* #return array An array of registered bundle names
*/
public function getBundles()
{
return $this->bundles;
}
/**
* Checks if a given class name belongs to an active bundle.
*
* #param string $class A class name
*
* #return Boolean true if the class belongs to an active bundle, false otherwise
*/
public function isClassInActiveBundle($class)
{
foreach ($this->bundles as $bundle) {
$bundleClass = get_class($bundle);
if (0 === strpos($class, substr($bundleClass, 0, strrpos($bundleClass, '\\')))) {
return true;
}
}
return false;
}
/**
* Returns the Bundle name for a given class.
*
* #param string $class A class name
*
* #return string The Bundle name or null if the class does not belongs to a bundle
*/
public function getBundleForClass($class)
{
$namespace = substr($class, 0, strrpos($class, '\\'));
foreach (array_keys($this->getBundleDirs()) as $prefix) {
if (0 === $pos = strpos($namespace, $prefix)) {
return substr($namespace, strlen($prefix) + 1, strpos($class, 'Bundle\\') + 7);
}
}
}
public function getName()
{
return $this->name;
}
public function getSafeName()
{
return preg_replace('/[^a-zA-Z0-9_]+/', '', $this->name);
}
public function getEnvironment()
{
return $this->environment;
}
public function isDebug()
{
return $this->debug;
}
public function getRootDir()
{
return $this->rootDir;
}
public function getContainer()
{
return $this->container;
}
public function getStartTime()
{
return $this->debug ? $this->startTime : -INF;
}
public function getCacheDir()
{
return $this->rootDir.'/cache/'.$this->environment;
}
public function getLogDir()
{
return $this->rootDir.'/logs';
}
protected function initializeContainer()
{
$class = $this->getSafeName().ucfirst($this->environment).($this->debug ? 'Debug' : '').'ProjectContainer';
$location = $this->getCacheDir().'/'.$class;
$reload = $this->debug ? $this->needsReload($class, $location) : false;
if ($reload || !file_exists($location.'.php')) {
$this->buildContainer($class, $location.'.php');
}
require_once $location.'.php';
$container = new $class();
$container->set('kernel', $this);
return $container;
}
public function getKernelParameters()
{
$bundles = array();
foreach ($this->bundles as $bundle) {
$bundles[] = get_class($bundle);
}
return array_merge(
array(
'kernel.root_dir' => $this->rootDir,
'kernel.environment' => $this->environment,
'kernel.debug' => $this->debug,
'kernel.name' => $this->name,
'kernel.cache_dir' => $this->getCacheDir(),
'kernel.logs_dir' => $this->getLogDir(),
'kernel.bundle_dirs' => $this->bundleDirs,
'kernel.bundles' => $bundles,
'kernel.charset' => 'UTF-8',
'kernel.compiled_classes' => array(),
),
$this->getEnvParameters()
);
}
protected function getEnvParameters()
{
$parameters = array();
foreach ($_SERVER as $key => $value) {
if ('SYMFONY__' === substr($key, 0, 9)) {
$parameters[strtolower(str_replace('__', '.', substr($key, 9)))] = $value;
}
}
return $parameters;
}
protected function needsReload($class, $location)
{
if (!file_exists($location.'.meta') || !file_exists($location.'.php')) {
return true;
}
$meta = unserialize(file_get_contents($location.'.meta'));
$time = filemtime($location.'.php');
foreach ($meta as $resource) {
if (!$resource->isUptodate($time)) {
return true;
}
}
return false;
}
protected function buildContainer($class, $file)
{
$parameterBag = new ParameterBag($this->getKernelParameters());
$container = new ContainerBuilder($parameterBag);
foreach ($this->bundles as $bundle) {
$bundle->registerExtensions($container);
if ($this->debug) {
$container->addObjectResource($bundle);
}
}
if (null !== $cont = $this->registerContainerConfiguration($this->getContainerLoader($container))) {
$container->merge($cont);
}
$container->freeze();
foreach (array('cache', 'logs') as $name) {
$dir = $container->getParameter(sprintf('kernel.%s_dir', $name));
if (!is_dir($dir)) {
if (false === #mkdir($dir, 0777, true)) {
die(sprintf('Unable to create the %s directory (%s)', $name, dirname($dir)));
}
} elseif (!is_writable($dir)) {
die(sprintf('Unable to write in the %s directory (%s)', $name, $dir));
}
}
// cache the container
$dumper = new PhpDumper($container);
$content = $dumper->dump(array('class' => $class));
if (!$this->debug) {
$content = self::stripComments($content);
}
$this->writeCacheFile($file, $content);
if ($this->debug) {
$container->addObjectResource($this);
// save the resources
$this->writeCacheFile($this->getCacheDir().'/'.$class.'.meta', serialize($container->getResources()));
}
}
protected function getContainerLoader(ContainerInterface $container)
{
$resolver = new LoaderResolver(array(
new XmlFileLoader($container, $this->getBundleDirs()),
new YamlFileLoader($container, $this->getBundleDirs()),
new IniFileLoader($container, $this->getBundleDirs()),
new PhpFileLoader($container, $this->getBundleDirs()),
new ClosureLoader($container),
));
return new DelegatingLoader($resolver);
}
/**
* Removes comments from a PHP source string.
*
* We don't use the PHP php_strip_whitespace() function
* as we want the content to be readable and well-formatted.
*
* #param string $source A PHP string
*
* #return string The PHP string with the comments removed
*/
static public function stripComments($source)
{
if (!function_exists('token_get_all')) {
return $source;
}
$output = '';
foreach (token_get_all($source) as $token) {
if (is_string($token)) {
$output .= $token;
} elseif (!in_array($token[0], array(T_COMMENT, T_DOC_COMMENT))) {
$output .= $token[1];
}
}
// replace multiple new lines with a single newline
$output = preg_replace(array('/\s+$/Sm', '/\n+/S'), "\n", $output);
// reformat {} "a la python"
$output = preg_replace(array('/\n\s*\{/', '/\n\s*\}/'), array(' {', ' }'), $output);
return $output;
}
protected function writeCacheFile($file, $content)
{
$tmpFile = tempnam(dirname($file), basename($file));
if (false !== #file_put_contents($tmpFile, $content) && #rename($tmpFile, $file)) {
chmod($file, 0644);
return;
}
throw new \RuntimeException(sprintf('Failed to write cache file "%s".', $file));
}
public function serialize()
{
return serialize(array($this->environment, $this->debug));
}
public function unserialize($data)
{
list($environment, $debug) = unserialize($data);
$this->__construct($environment, $debug);
}
}
Your answer lies in the imported namespaces. In the Kernel's file, there's this use clause:
use Symfony\Component\DependencyInjection\Loader\LoaderInterface;
So that ties LoaderInterface to the fully namespaced class Symfony\Component\DependencyInjection\Loader\LoaderInterface.
Basically making the signature:
public function registerContainerConfiguration(Symfony\Component\DependencyInjection\Loader\LoaderInterface $loader);
In your class, you don't import that namespace. So PHP by default assumes the class is in your namespace (since none of the imported namespaces have that interface name).
So your signature is (since you don't declare a namespace):
public function registerContainerConfiguration(\LoaderInterface $loader);
So to get them to match, simply add the use line to the top of your file:
use Symfony\Component\DependencyInjection\Loader\LoaderInterface;