I have installed Poppler Utils for windows in addition to https://github.com/mgufrone/pdf-to-html
It works perfectly and it converts PDF files to HTML, by making a single HTML file contains 2 iframes, one for pages navigation and the other for the actual text.
The problem is when the HTML files are generated, the linking for iframe src gives a false linking.
For Example:
Test.html
Pages.html
Page_1.html
All these files exist in the same folder named "Output".
Test.html contains 2 iframes linking to Pages.html and Page_1.html
Here's the problem in Test.html:
<frameset cols="100,*">
<frame name="links" src="output/Pages.html"/>
<frame name="contents" src="output/Pages_1.html"/>
</frameset>
Should be:
<frameset cols="100,*">
<frame name="links" src="Pages.html"/>
<frame name="contents" src="Pages_1.html"/>
</frameset>
PDF.php
<?php namespace Gufy\PdfToHtml;
class Pdf
{
protected $file, $info;
// protected $info_bin = '/usr/bin/pdfinfo';
public function __construct($file, $options=array())
{
$this->file = $file;
$class = $this;
array_walk($options, function($item, $key) use($class){
$class->$key = $item;
});
return $this;
}
public function getInfo()
{
if($this->info == null)
$this->info($this->file);
return $this->info;
}
protected function info()
{
$content = shell_exec($this->bin().' '.$this->file);
// print_r($info);
$options = explode("\n", $content);
$info = array();
foreach($options as &$item)
{
if(!empty($item))
{
list($key, $value) = explode(":", $item);
$info[str_replace(array(" "),array("_"),strtolower($key))] = trim($value);
}
}
// print_r($info);
$this->info = $info;
return $this;
// return $content;
}
public function html()
{
if($this->info == null)
$this->info($this->file);
return new Html($this->file);
}
public function getPages()
{
if($this->info == null)
$this->info($this->file);
return $this->info['pages'];
}
public function bin()
{
return Config::get('pdfinfo.bin', '/usr/bin/pdfinfo');
}
}
Base.php
<?php
namespace Gufy\PdfToHtml;
class Base
{
private $options=array(
'singlePage'=>false,
'imageJpeg'=>false,
'ignoreImages'=>false,
'zoom'=>1.5,
'noFrames'=>true,
);
public $outputDir;
private $bin="/usr/bin/pdftohtml";
private $file;
public function __construct($pdfFile='', $options=array())
{
if(empty($pdfFile))
return $this;
$pdf = $this;
if(!empty($options))
array_walk($options, function($value, $key) use($pdf){
$pdf->setOptions($key, $value);
});
return $this->open($pdfFile);
}
public function open($pdfFile)
{
$this->file = $pdfFile;
$this->setOutputDirectory(dirname($pdfFile));
return $this;
}
public function html()
{
$this->generate();
$file_output = $this->outputDir."/".preg_replace("/\.pdf$/","",basename($this->file)).".html";
$content = file_get_contents($file_output);
unlink($file_output);
return $content;
}
/**
* generating html files using pdftohtml software.
* #return $this current object
*/
public function generate(){
$output = $this->outputDir."/".preg_replace("/\.pdf$/","",basename($this->file)).".html";
$options = $this->generateOptions();
$command = $this->bin()." ".$options." ".$this->file." ".$output;
$result = exec($command);
return $this;
}
/**
* generate options based on the preserved options
* #return string options that will be passed on running the command
*/
public function generateOptions()
{
$generated = array();
array_walk($this->options, function($value, $key) use(&$generated){
$result = "";
switch($key)
{
case "singlePage":
$result = $value?"-c":"-s";
break;
case "imageJpeg":
$result = "-fmt ".($value?"jpg":"png");
break;
case "zoom":
$result = "-zoom ".$value;
break;
case "ignoreImages":
$result = $value?"-i":"";
break;
case 'noFrames':
$result = $value?'-noframes':'';
break;
}
$generated[] = $result;
});
return implode(" ", $generated);
}
/**
* change value of preserved configuration
* #param string $key key of option you want to change
* #param mixed $value value of option you want to change
* #return $this current object
*/
public function setOptions($key, $value)
{
if(isset($this->options[$key]))
$this->options[$key] = $value;
return $this;
}
/**
* open pdf file that will be converted. make sure it is exists
* #param string $pdfFile path to pdf file
* #return $this current object
*/
public function setOutputDirectory($dir)
{
$this->outputDir=$dir;
return $this;
}
/**
* clear the whole files that has been generated by pdftohtml. Make sure directory ONLY contain generated files from pdftohtml
* because it remove the whole contents under preserved output directory
* #return $this current object
*/
public function clearOutputDirectory()
{
$files = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->outputDir, \FilesystemIterator::SKIP_DOTS));
foreach($files as $file)
{
$path = (string)$file;
$basename = basename($path);
if($basename != '..')
{
if(is_file($path) && file_exists($path))
unlink($path);
elseif(is_dir($path) && file_exists($path))
rmdir($path);
}
}
return $this;
}
public function bin()
{
return Config::get('pdftohtml.bin', '/usr/bin/pdftohtml');
}
}
Related
I had built a PHP back-end and I just want to make a simple interface for it using react js and I am using CLI script for running the PHP so I am not using any framework just PHP so this is the PHP file that I build and just I want to know how to connect PHP back-end to react js if you can help me with it or give me some link to follow it.
<?PHP
/**
* The interface provides the contract for different readers
* E.g. it can be XML/JSON Remote Endpoint, or CSV/JSON/XML local files
*/
interface ReaderInterface
{
/**
* Read in incoming data and parse to objects
*/
public function read(string $input): OfferCollectionInterface;
}
/**
* Interface of Data Transfer Object, that represents external JSON data
*/
interface OfferInterface
{
}
/**
* Interface for The Collection class that contains Offers
*/
interface OfferCollectionInterface
{
public function get(int $index): OfferInterface;
public function getIterator(): Iterator;
}
/* *********************************** */
class Offer implements OfferInterface
{
public $offerId;
public $productTitle;
public $vendorId;
public $price;
public function __toString(): string
{
return "$this->offerId | $this->productTitle | $this->vendorId | $this->price\n";
}
}
class OfferCollection implements OfferCollectionInterface
{
private $offersList = array();
public function __construct($data)
{
foreach ($data as $json_object) {
$offer = new Offer();
$offer->offerId = $json_object->offerId;
$offer->productTitle = $json_object->productTitle;
$offer->vendorId = $json_object->vendorId;
$offer->price = $json_object->price;
array_push($this->offersList, $offer);
}
}
public function get(int $index): OfferInterface
{
return $this->offersList[$index];
}
public function getIterator(): Iterator
{
return new ArrayIterator($this->offersList);
}
public function __toString(): string
{
return implode("\n", $this->offersList);
}
}
class Reader implements ReaderInterface
{
/**
* Read in incoming data and parse to objects
*/
public function read(string $input): OfferCollectionInterface
{
if ($input != null) {
$content = file_get_contents($input);
$json = json_decode($content);
$result = new OfferCollection($json);
return $result;
}
return new OfferCollection(null);
}
}
class Logger {
private $filename = "logs.txt";
public function info($message): void {
$this->log($message, "INFO");
}
public function error($message): void {
$this->log($message, "ERROR");
}
private function log($message, $type): void {
$myfile = fopen($this->filename, "a") or die("Unable to open file!");
$txt = "[$type] $message\n";
fwrite($myfile, $txt);
fclose($myfile);
}
}
$json_url = 'data.json';
$json_reader = new Reader();
$offers_list = $json_reader->read($json_url);
function count_by_price_range($price_from, $price_to)
{
global $offers_list;
$count = 0;
foreach ($offers_list->getIterator() as $offer) {
if ($offer->price >= $price_from && $offer->price <= $price_to) {
$count++;
}
}
return $count;
}
function count_by_vendor_id($vendorId)
{
global $offers_list;
$count = 0;
foreach ($offers_list->getIterator() as $offer) {
if ($offer->vendorId == $vendorId) {
$count++;
}
}
return $count;
}
$cli_args = $_SERVER['argv'];
$function_name = $cli_args[1];
$logger = new Logger();
switch ($function_name) {
case "count_by_price_range": {
$logger->info("Getting Count By Price Range From: $cli_args[2] TO $cli_args[3]");
echo count_by_price_range($cli_args[2], $cli_args[3]);
break;
}
case "count_by_vendor_id": {
$logger->info("Getting Count By vendor Id: $cli_args[2]");
echo count_by_vendor_id($cli_args[2]);
break;
}
}
Reactjs is frontend and PHP is backend, you can connect between React App and PHP services by REST API
I have opencart 3 installed on my dev box and have suddenly started getting the following error:
Fatal error: Class Twig_Loader_Filesystem contains 2 abstract methods
and must therefore be declared abstract or implement the remaining
methods (Twig_LoaderInterface::isFresh,
Twig_ExistsLoaderInterface::exists) in
/mnt/c/wsl/server/opencart/system/library/template/Twig/Loader/Filesystem.php
on line 17
I have been working on a custom template and all was going fine until I changed something in the controller of the footer. Changing it back did not resolve the issue. I have also manually cleared the cache in the OC folder and the twig folder. I also did not have the cache setting set to off so I manually made this change in the db as I get the same error trying to get into the admin.
I am at a loss. I would love any help I could get.
Call Stack
{main}( )
start( )
require_once( '/mnt/c/wsl/server/opencart/system/framework.php' )
Router->dispatch( )
Router->execute( )
Action->execute( )
ControllerStartupRouter->index( )
Action->execute( )
ControllerCommonHome->index( )
Loader->controller( )
Action->execute( )
ControllerCommonColumnLeft->index( )
Loader->view( )
Template->render( )
Template\Twig->render( )
spl_autoload_call ( )
Twig_Autoloader::autoload( )
require( '/mnt/c/wsl/server/opencart/system/library/template/Twig/Loader/Filesystem.php'
)
Location
.../index.php:0
.../index.php:19
.../startup.php:104
.../framework.php:165
.../router.php:56
.../router.php:67
.../action.php:79
.../router.php:25
.../action.php:79
.../home.php:12
.../loader.php:48
.../action.php:79
.../column_left.php:72
.../loader.php:125
.../template.php:51
.../twig.php:20
.../twig.php:20
.../Autoloader.php:51
class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderInterface
{
/** Identifier of the main namespace. */
const MAIN_NAMESPACE = '__main__';
protected $paths = array();
protected $cache = array();
protected $errorCache = array();
/**
* Constructor.
*
* #param string|array $paths A path or an array of paths where to look for templates
*/
public function __construct($paths = array())
{
if ($paths) {
$this->setPaths($paths);
}
}
/**
* Returns the paths to the templates.
*
* #param string $namespace A path namespace
*
* #return array The array of paths where to look for templates
*/
public function getPaths($namespace = self::MAIN_NAMESPACE)
{
return isset($this->paths[$namespace]) ? $this->paths[$namespace] : array();
}
/**
* Returns the path namespaces.
*
* The main namespace is always defined.
*
* #return array The array of defined namespaces
*/
public function getNamespaces()
{
return array_keys($this->paths);
}
/**
* Sets the paths where templates are stored.
*
* #param string|array $paths A path or an array of paths where to look for templates
* #param string $namespace A path namespace
*/
public function setPaths($paths, $namespace = self::MAIN_NAMESPACE)
{
if (!is_array($paths)) {
$paths = array($paths);
}
$this->paths[$namespace] = array();
foreach ($paths as $path) {
$this->addPath($path, $namespace);
}
}
/**
* Adds a path where templates are stored.
*
* #param string $path A path where to look for templates
* #param string $namespace A path name
*
* #throws Twig_Error_Loader
*/
public function addPath($path, $namespace = self::MAIN_NAMESPACE)
{
// invalidate the cache
$this->cache = $this->errorCache = array();
if (!is_dir($path)) {
throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist.', $path));
}
$this->paths[$namespace][] = rtrim($path, '/\\');
}
/**
* Prepends a path where templates are stored.
*
* #param string $path A path where to look for templates
* #param string $namespace A path name
*
* #throws Twig_Error_Loader
*/
public function prependPath($path, $namespace = self::MAIN_NAMESPACE)
{
// invalidate the cache
$this->cache = $this->errorCache = array();
if (!is_dir($path)) {
throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist.', $path));
}
$path = rtrim($path, '/\\');
if (!isset($this->paths[$namespace])) {
$this->paths[$namespace][] = $path;
} else {
array_unshift($this->paths[$namespace], $path);
}
}
/**
* {#inheritdoc}
*/
public function getSource($name)
{
return file_get_contents($this->findTemplate($name));
}
/**
* {#inheritdoc}
*/
public function getCacheKey($name)
{
return $this->findTemplate($name);
}
/**
* {#inheritdoc}
*/
public function exists($name)
{
$name = $this->normalizeName($name);
if (isset($this->cache[$name])) {
return true;
}
try {
return false !== $this->findTemplate($name, false);
} catch (Twig_Error_Loader $exception) {
return false;
}
}
/**
* {#inheritdoc}
*/
public function isFresh($name, $time)
{
return filemtime($this->findTemplate($name)) <= $time;
}
protected function findTemplate($name)
{
$throw = func_num_args() > 1 ? func_get_arg(1) : true;
$name = $this->normalizeName($name);
if (isset($this->cache[$name])) {
return $this->cache[$name];
}
if (isset($this->errorCache[$name])) {
if (!$throw) {
return false;
}
throw new Twig_Error_Loader($this->errorCache[$name]);
}
$this->validateName($name);
list($namespace, $shortname) = $this->parseName($name);
if (!isset($this->paths[$namespace])) {
$this->errorCache[$name] = sprintf('There are no registered paths for namespace "%s".', $namespace);
if (!$throw) {
return false;
}
throw new Twig_Error_Loader($this->errorCache[$name]);
}
foreach ($this->paths[$namespace] as $path) {
if (is_file($path.'/'.$shortname)) {
if (false !== $realpath = realpath($path.'/'.$shortname)) {
return $this->cache[$name] = $realpath;
}
return $this->cache[$name] = $path.'/'.$shortname;
}
}
$this->errorCache[$name] = sprintf('Unable to find template "%s" (looked into: %s).', $name, implode(', ', $this->paths[$namespace]));
if (!$throw) {
return false;
}
throw new Twig_Error_Loader($this->errorCache[$name]);
}
protected function parseName($name, $default = self::MAIN_NAMESPACE)
{
if (isset($name[0]) && '#' == $name[0]) {
if (false === $pos = strpos($name, '/')) {
throw new Twig_Error_Loader(sprintf('Malformed namespaced template name "%s" (expecting "#namespace/template_name").', $name));
}
$namespace = substr($name, 1, $pos - 1);
$shortname = substr($name, $pos + 1);
return array($namespace, $shortname);
}
return array($default, $name);
}
protected function normalizeName($name)
{
return preg_replace('#/{2,}#', '/', str_replace('\\', '/', (string) $name));
}
protected function validateName($name)
{
if (false !== strpos($name, "\0")) {
throw new Twig_Error_Loader('A template name cannot contain NUL bytes.');
}
$name = ltrim($name, '/');
$parts = explode('/', $name);
$level = 0;
foreach ($parts as $part) {
if ('..' === $part) {
--$level;
} elseif ('.' !== $part) {
++$level;
}
if ($level < 0) {
throw new Twig_Error_Loader(sprintf('Looks like you try to load a template outside configured directories (%s).', $name));
}
}
}
}
I've made a website in symfony. This website contains some forms with a checkbox choice and other fields.
The datas from the checkbox are serialized on flush.
It's all good.
Now i have to export this datas and i use the data exporter library from Sonata project. But the datas are still serialized and i have some things like that in my csv file:
a:2:{i:0;s:6:"Volets";i:1;s:22:"Panneau de remplissage";}
How can I unserialize my datas in order to have a clean csv file?
Here's my code
My controller
/**
* #Security("has_role('ROLE_WEBFORM')")
*/
public function exportAction(Request $request)
{
$filters = array();
$this->handleFilterForm($request, $filters);
if (!$filters['webform']) {
throw $this->createNotFoundException();
}
$webForm = $this->getRepository('CoreBundle:WebForm')->find($filters['webform']);
$source = new WebFormEntryIterator($webForm, $this->getEntityManager(), $this->get('ines_core.embedded_form.field_type_registry'), $filters);
return WebFormEntryExporter::createResponse('export.csv', $source);
}
and my class WebFormEntryExporter
class WebFormEntryExporter
{
public static function createResponse($filename, SourceIteratorInterface $source)
{
$writer = new CsvWriter('php://output', ';', '"', "", true, true);
$contentType = 'text/csv';
$callback = function() use ($source, $writer) {
$handler = \Exporter\Handler::create($source, $writer);
$handler->export();
};
return new StreamedResponse($callback, 200, [
'Content-Type' => $contentType,
'Content-Disposition' => sprintf('attachment; filename=%s', $filename)
]);
}
}
And my WebFormEntryIterator
class WebFormEntryIterator implements SourceIteratorInterface
{
protected $em;
protected $registry;
protected $repository;
protected $query;
protected $webForm;
protected $iterator;
public function __construct(WebForm $webForm, EntityManager $em, FieldTypeRegistry $registry, array $filters)
{
$this->webForm = $webForm;
$this->em = $em;
$this->registry = $registry;
$this->initQuery($filters);
}
/**
* {#inheritdoc}
*/
public function current()
{
$current = $this->iterator->current();
$entity = $current[0];
$data = [];
$data['ID'] = $entity->getId();
$data['Formulaire'] = $this->webForm->getName();
$data['Date de création'] = date_format($entity->getCreatedAt(), 'd/m/Y H:i:s');
foreach ($this->webForm->getEmbeddedFieldConfigs() as $fieldConfig) {
$header = $fieldConfig->getLabel();
$meta = $entity->getContentMeta($fieldConfig->getName());
$extension = $this->registry->get($meta->getFormat());
if (method_exists($extension, 'setEntityManager')) {
$extension->setEntityManager($this->em);
}
$value = $extension->formatMeta($meta);
$data[$header] = $value;
unset($extension);
}
$this->query->getEntityManager()->getUnitOfWork()->detach($current[0]);
unset($entity);
unset($webForm);
return $data;
}
/**
* {#inheritdoc}
*/
public function next()
{
$this->iterator->next();
}
/**
* {#inheritdoc}
*/
public function key()
{
return $this->iterator->key();
}
/**
* {#inheritdoc}
*/
public function valid()
{
return $this->iterator->valid();
}
/**
* {#inheritdoc}
*/
public function rewind()
{
if ($this->iterator) {
throw new InvalidMethodCallException('Cannot rewind a Doctrine\ORM\Query');
}
$this->iterator = $this->query->iterate();
$this->iterator->rewind();
}
protected function initQuery(array $filters)
{
$repository = $this->em->getRepository('InesCoreBundle:Content');
$qb = $repository->getWebFormEntryQueryBuilder();
$repository->applyWfeFilters($qb, $filters);
$this->query = $qb->getQuery();
}
}
Sorry for my broken English.
Thanks a lot
thanks chalasr.
I have to make the tratment in this file, in the current() function.
This is what I've done:
public function current()
{
$current = $this->iterator->current();
$entity = $current[0];
$data = [];
$data['ID'] = $entity->getId();
$data['Formulaire'] = $this->webForm->getName();
$data['Date de création'] = date_format($entity->getCreatedAt(), 'd/m/Y H:i:s');
foreach ($this->webForm->getEmbeddedFieldConfigs() as $fieldConfig) {
$header = $fieldConfig->getLabel();
$meta = $entity->getContentMeta($fieldConfig->getName());
$extension = $this->registry->get($meta->getFormat());
if (method_exists($extension, 'setEntityManager')) {
$extension->setEntityManager($this->em);
}
$value = $extension->formatMeta($meta);
if($this->is_serialized($value)) {
$value = unserialize($value);
$data[$header] = implode(' | ', $value);
} else {
$data[$header] = $value;
}
unset($extension);
}
$this->query->getEntityManager()->getUnitOfWork()->detach($current[0]);
unset($entity);
unset($webForm);
return $data;
}
public function is_serialized($data)
{
if (trim($data) == "") { return false; }
if (preg_match("/^(i|s|a|o|d){1}:{1}(.*)/si",$data)) { return true; }
return false;
}
EDITED to add code for MainClass as requested in comments.
I'm trying to learn how to make php packages and how to use phpunit at the same time, I may be using all the wrong terminology here and doing everything wrong..
Everything works as expected when I import the package with composer. I decided to add some unit tests as I finally started to see how they could be useful to me however I am having trouble and I suspect it has something to do with namespaces but I'm not sure.
I have put the tests in their own directory and used use statements at the top of the test classes for importing the main src classes. So, for example, in a test class I have the following:
use myname\Package\MainClass;
use myname\Package\Resources\Resource;
use myname\Package\Resources\ExtendedResource;
class ResourceTest extends PHPUnit_Framework_TestCase {
public function testArtistIsResource() {
$resource = '\\myname\\Package\\Resources\\Resource';
$main = new MainClass('Artist');
$artist = $main->find(1383508);
$this->assertTrue($artist instanceof $resource);
}
}
This test passes. I am running the same code outside of the test directory and displaying values in the browser to see what happens. I am running the package in laravel and just running the comparison code on the homepage. For example the output of the following code is printed directly in the browser
$main = new MainClass('Artist');
$artist = $main->find(1383508);
echo get_class($main);
echo get_class($artist);
This shows that $main is a myname\Package\MainClass and $artist is a myname\Package\Resources\ExtendedResource. If I change the second echo statement above to this:
echo get_class($artist->get());
Then the result is that stdClass is echoed to the screen, which is correct. However in the test class $artist->get() returns an instance of ResourceTest and I don't understand why it is not another stdClass.
What am I missing?
My directory structure is as follows:
myname
|- Package
|- composer.json
|- src
|- MainClass.php
|- Resources
|- Resource.php
|- ExtendsResource.php
|- tests
|- Resources
|- ResourceTest.php
Below is the content of the autoload part of composer.json
"autoload": {
"psr-4": {
"myname\\Package\\": "src/"
}
}
I tried adding another namespace in there - "myname\Package\tests\": "tests/" - but that didn't seem to help.
The namespace for MainClass.php is myname\Package.
The namespace for Resources.php and ExtendsResources.php is myname\Package\Resources.
Here is the code for MainClass.php
<?php
namespace myname\Package;
class MainClass {
private $resource;
public function __construct($resource = null) {
Container::setup();
if ($resource) {
$this->resource = Container::get($resource);
}
return $this->resource;
}
public function find($id) {
if (isset ($this->resource)) {
$this->resource->find($id);
return $this->resource;
}
else { throw new \Exception('Resource is not set'); }
}
public function setResource($resource) {
$this->resource = Container::get($resource);
return $this->resource;
}
}
Below is the code for myname\Package\Resources\Reource
<?php
namespace myname\Package\Resources;
use myname\Package\Contracts\ConfigInterface;
use myname\Package\Contracts\GrabberInterface;
use myname\Package\Contracts\ResourceInterface;
use myname\Package\Http\Grabber;
use myname\Package\Http\Poster;
abstract class Resource {
protected $config = null;
protected $url = null;
protected $resource = null;
protected $response = null;
protected $grabber = null;
protected $perPage = null;
protected $page = null;
protected $params = null;
protected $token = null;
protected $identifier = null;
protected $update = array();
protected $appendTokenTo = array(
'myname\Package\Resources\Artist',
'myname\Package\Resources\Listing',
'myname\Package\Resources\Release',
'myname\Package\Resources\Search'
);
public function __construct($config, $grabber) {
if ($config instanceof ConfigInterface) {
$this->config = $config;
} else { throw new \Exception('The supplied $config is not an instance of ConfigInterface'); }
if ($grabber instanceof GrabberInterface) {
$this->grabber = $grabber;
} else { throw new \Exception('The supplied $grabber is not an instance of GrabberInterface'); }
$this->url .= $this->config->getApiUrl() . $this->resource;
$this->token = $this->config->getApiToken();
return $this;
}
public function addParam($param, $value) {
$value= $this->formatParamValue($value);
$this->params .= "&". "$param=$value";
return $this;
}
protected function addToken(){
$this->addParam('token', $this->token);
//$this->params .= "&". "token=$this->token";
return $this;
}
public function addUpdate($update, $value) {
$this->update[$update] = $value;
return $this;
}
protected function checkIfTokenIsRequired() {
if (in_array(get_class($this), $this->appendTokenTo)) {
$this->addToken();
}
}
public function find($identifier) {
if (empty ($this->identifier)) {
$this->identifier = $identifier;
$this->url .= "/$identifier";
}
return $this;
}
protected function formatParamValue($value) {
$value = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $value);
$value = str_replace(' ', '+', $value);
return $value;
}
public function get() {
return json_decode($this->getResponse());
}
protected function getResponse() {
if (!isset($this->response)) {
$this->checkIfTokenIsRequired();
$this->_prepare();
}
return $this->response;
}
public function json() {
return $this->getResponse();
}
public function page($pageNumber) {
$this->page = $pageNumber;
return $this;
}
public function perPage($resultsPerPage) {
$this->perPage = $resultsPerPage;
return $this;
}
protected function _prepare() {
$params = 0;
if (isset($this->page) OR isset($this->perPage) OR isset($this->params)){
$this->url .= '?';
}
if (isset($this->params)) {
$this->url .= "$this->params";
$params++;
}
if (isset($this->perPage)) {
if ($params > 0) {
$this->url .= '&';
}
$this->url .= "per_page=$this->perPage";
$params++;
}
if (isset($this->page)) {
if ($params > 0) {
$this->url .= '&';
}
$this->url .= "page=$this->page";
$params++;
}
$this->grabber->setUrl($this->url);
$this->response = $this->grabber->grab();
}
public function setGrabber($grabber) {
if ($grabber instanceof GrabberInterface) {
$this->grabber = $grabber;
} else { throw new \Exception($grabber . " is not an instance of GrabberInterface"); }
}
public function setUrl($url) {
$this->url = $url;
}
public function update() {
//$this->update['token'] = $this->token;
$this->grabber->setMethod('POST');
$this->grabber->setUpdates(json_encode($this->update));
$this->_prepare();
return $this;
}
}
Below is the code for the ExtendedResource
<?php
namespace myname\Package\Resources;
class ExtendedResource extends Resource {
protected $resource = 'artists';
/**
* Returns the releases associated with an artist
*
* #return $this
*/
public function releases() {
$this->url .= '/releases';
return $this;
}
}
I have a script that works perfect in ubuntu, recently I copied the exact same script to centos6 server
and I'm getting the following error:
PHP Warning: array_map(): Argument #2 should be an array in /copy_scripts/classes/Vserver.class.php on line 245
the code
/**
* Get an array of open files
* #param array $aExt
* #return array of arrays ['views','size','path']
*/
public function getOpenFiles($aExt=array()) {
$aOpenFiles = self::GetList(self::$sLogOpenFiles);
$aOpenFiles = array_map( create_function('$v', '
$v = trim($v);
$aFile = preg_split("#[\t\s]+#",$v);
$oFile = new VserverFile($aFile[2]);
$oFile->setViews($aFile[0]);
return $oFile;'),
$aOpenFiles
);
//echo "<pre>";
//print_r($aOpenFiles);
return $aOpenFiles;
}
Can it be the difference between php versions?
centos:
PHP 5.3.3 (cli) (built: Jul 3 2012 16:53:21)
ubuntu
PHP 5.3.10-2 (cli) (built: Feb 20 2012 19:39:00)
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies
what I've tried so far:
changing setting in php.ini a restarting php.
the complete code:
<?php
/**
*
* Global Video Server class
* Singleton class
* Has methods to manipulate files
* #author kpoxas
*
*/
class Vserver {
static protected $oInstance=null;
static protected $iTimeStart, $iTimeEnd;
const FILE_NOEXIST = -2;
const FILE_ZEROSIZE = -4;
const FILE_DIFF = -8;
/*
* Path /var/www/HDD_PATH/
*/
static public $sHDDPath = null;
/*
* Path /var/www/SSD_PATH/
*/
static public $sSSDPath = null;
/*
* Folder same on every RAID.../FOLDER/...
*/
static public $sHTTPFolder = null;
/*
* Open Files Log
*/
static public $sLogOpenFiles = null;
/*
* Limit of Free space on SSD in percents
*/
static public $iSSDUsage = 90;
/*
* Limit of Free space on SSD in percents (not delete below)
*/
static public $iSSDDeleteUsage = 80;
/*
* Limit of Free space on SSD in bytes (not delete below)
*/
static public $iSSDDeleteUsageAbsolute = 5368709120;
/*
* Min views count of file to copy
*/
static public $iMinViews = 2;
/*
* Search within files older than $iDaysToDelete days
*/
static public $iDaysToDelete = 1;
/*
* Test Mode
* File manipulations aren't executed
* Only log mode
*/
static public $bTest = false;
/*
* Store openfiles.txt log
*/
static protected $sOpenFiles = null;
/**
* Äåñêðèïòîð áëîêèðóþùåãî ôàéëà
*
* #var string
*/
protected $oLockFile=null;
/**
* Singleton Object implementation
*
* #return VSERVER
*/
static public function getInstance() {
if (isset(self::$oInstance) and (self::$oInstance instanceof self)) {
return self::$oInstance;
} else {
self::$oInstance= new self();
return self::$oInstance;
}
}
/**
* Get Log content
* #param string $sLogPath
* #return string
*/
static public function GetLog($sLogPath) {
if ($s = #file_get_contents($sLogPath)) {
$s = trim($s);
if (!empty($s)) {
return $s;
}
}
return false;
}
/**
* Get Log content in list mode divided by EOL
* #param string $sLogPath
* #return array
*/
static public function GetList($sLogPath) {
if ($sList = self::GetLog($sLogPath)) {
return explode(PHP_EOL,trim($sList));
}
}
/**
* Check if directory exists and chmod 775
* #param $directory
*/
static public function CheckDirectory($directory) {
$directory = rtrim($directory, '/\\');
if (is_dir($directory)) #chmod($directory, 0775);
else {
if (!mkdir($directory, 0755, true)) {
//self::AddError ('Directory does not exist', $directory);
return false;
}
}
}
/**
* Check if file exist
* Check if file has zero size
* #param string $filename
*/
static public function CheckFile($filename) {
if (file_exists($filename) && !is_file($filename)) {
self::log("NO VALID FILEPATH: {$filename}");
return false;
} else if(!file_exists($filename)) {
self::log("FILE DOESN'T EXIST: {$filename}");
return self::FILE_NOEXIST;
} else if(!filesize($filename)) {
self::log("FILE ZEROSIZE: {$filename}");
return self::FILE_ZEROSIZE;
}
else return true;
}
/**
* Check if file1 is identical to file2
* #param string $filename1
* #param string $filename2
*/
static public function CheckIdentity($filename1, $filename2) {
if (self::CheckFile($filename1)>0 && self::CheckFile($filename2)>0) {
if (filesize($filename1)===filesize($filename2)) {
self::log("FILES: {$filename1} AND {$filename2} ARE IDENTICAL");
return true;
}
self::log("FILES: {$filename1} AND {$filename2} ARE DIFFERENT");
return false;
}
}
/**
* Copy file from $source to $dest
* Make www-data owner
* Make perms 755
*/
static public function Copy($source, $dest = null) {
self::log("COPY {$source} TO {$dest}");
if (self::$bTest) return true;
self::CheckDirectory(dirname($dest));
// copy
$sCmd = "cp -f '{$source}' '{$dest}'";
self::exec($sCmd);
// chown
$sCmdChown = "chown www-data:www-data '{$dest}'";
self::exec($sCmdChown);
// chmod
$sCmdChmod = "chmod 775 '{$dest}'";
self::exec($sCmdChmod);
return true;
}
/**
* Delete file
*/
static public function Delete($source) {
self::log("DELETE {$source}");
if (self::$bTest) return true;
// chmod
$sCmdChmod = "rm '{$source}'";
self::exec($sCmdChmod);
}
/**
* Get free space of catalog or storage in bytes
* #param string $sDir
*/
static public function GetFreeSpace($sDir = '') {
return disk_free_space($sDir);
}
/**
* Get total space of catalog or storage in bytes
* #param string $sDir
*/
static public function GetTotalSpace($sDir = '') {
return disk_total_space($sDir);
}
/**
* Get used space of catalog or storage in percents
* #param string $sDir
*/
static public function GetUsage($sDir = '') {
//$sCmd = "df -k {$sDir} | grep -Eo '[0-9]+%'";
//return intval(self::exec($sCmd));
return round(1-self::GetFreeSpace($sDir)/self::GetTotalSpace($sDir),4)*100;
}
/**
* Exec command wrapper
*/
static public function exec($sCmd = null, &$aVar=null) {
if (empty($sCmd)) {
return;
}
self::log($sCmd);
return exec($sCmd, $aVar);
}
static public function log($sStr) {
echo "{$sStr}<br>\n";
}
/**
* Get open files log
* #return string
*/
static public function getOpenFilesContent() {
if (self::$sOpenFiles === null) {
self::$sOpenFiles = self::GetLog(self::$sLogOpenFiles);
}
return self::$sOpenFiles;
}
/**
* Get an array of open files
* #param array $aExt
* #return array of arrays ['views','size','path']
*/
public function getOpenFiles($aExt=array()) {
$aOpenFiles = self::GetList(self::$sLogOpenFiles);
$aOpenFiles = array_map( create_function('$v', '
$v = trim($v);
$aFile = preg_split("#[\t\s]+#",$v);
$oFile = new VserverFile($aFile[2]);
$oFile->setViews($aFile[0]);
return $oFile;'),
$aOpenFiles
);
//echo "<pre>";
//print_r($aOpenFiles);
return $aOpenFiles;
}
public function getFileList($sDir=null, $aExt=array('flv','mp4'), $sGrep='') {
if (!$sDir || empty($aExt)) return;
$aCmdExt = "\( -name '*."
.implode("' -o -name '*.",$aExt)
."' \)";
$sCmd = "find {$sDir} {$aCmdExt} -mmin +".self::$iDaysToDelete."";
// sort by date
//$sCmd = "find {$sDir} {$aCmdExt} -printf '%T# %p\n'| sort -k 1n | cut -d' ' -f2-";
if (!empty($sGrep)) {
$sCmd.= " | {$sGrep}";
}
self::exec($sCmd,$aFiles);
return $aFiles;
}
/**
*
* Get list of storages
*/
public function getStorages() {
$sCmd = "df -k | grep -Eo 'storage[0-9]+$'";
self::exec($sCmd,$aStorages);
return $aStorages;
}
/**
*
* Get list of megastorages
*/
public function getMegaStorages() {
$sCmd = "df -k | sort -k5 -r | grep -Eo 'megastorage[0-9]+$'";
self::exec($sCmd,$aStorages);
return $aStorages;
}
/**
* Copy opened files to SSD
*/
public function copyToSSD() {
$this->setLock(__FUNCTION__.'.lock');
if($this->isLock()) {
self::log("Process has already started.");
return;
}
$iCopied = 0;
$iIgnored = 0;
$aOpenedFiles = $this->GetOpenFiles();
foreach ($aOpenedFiles as $oFile) {
if (self::GetUsage(self::$sSSDPath) < self::$iSSDUsage) {
if ($oFile->getViews() >=self::$iMinViews && $oFile->synchronize()) $iCopied++;
else $iIgnored++;
} else {
break;
}
}
self::log("COPIED: {$iCopied}");
self::log("IGNORED: {$iIgnored}");
self::log("SSD USAGE: ".self::GetUsage(self::$sSSDPath)."%");
}
/**
* DELETE FROM SSD
*/
public function deleteFromSSD() {
$this->setLock(__FUNCTION__.'.lock');
if($this->isLock()) {
self::log("Process has already started.");
return;
}
$iDeleted = 0;
$iIgnored = 0;
/*
* Get megastorages sorted by usage desc,
*/
$aMegaStorages = $this->getMegaStorages();
foreach ($aMegaStorages as &$sMegaStorage) {
/*
* Get files in current megastorage
*/
$aFileList = $this->getFileList('/'.$sMegaStorage);
if (empty($aFileList)) {
self::log("NO FILES FOUND in {$sMegaStorage}");
continue;
}
$aFileList = array_map(
create_function('$v', '
$oFile = new VserverFile(trim($v));
return $oFile;
'),
$aFileList
);
/*
* Delete files until appropriate usage
*/
$iFreeSpace = self::GetFreeSpace('/'.$sMegaStorage);
$iTotalSpace = self::GetTotalSpace('/'.$sMegaStorage);
foreach ($aFileList as &$oFile) {
$iUsageCurrent = round(1-$iFreeSpace/$iTotalSpace,4)*100;
self::Log($sMegaStorage." ".$iUsageCurrent."%");
if ($iUsageCurrent > self::$iSSDDeleteUsage) {
if (!$oFile->isOpened()) {
$iFreeSpace += $oFile->getSize();
$oFile->synchronize();
$oFile->deleteFromSSD();
$iDeleted++;
} else $iIgnored++;
} else {
break;
}
}
}
/*
$aFileList = $this->getFileList(self::$sSSDPath);
if (empty($aFileList)) {
self::log("NO FILES FOUND");
return;
}
$aFileList = array_map(
create_function('$v', '
$oFile = new VserverFile(trim($v));
return $oFile;
'),
$aFileList
);
foreach ($aFileList as $oFile) {
if (self::GetUsage(self::$sSSDPath) > self::$iSSDDeleteUsage) {
if (!$oFile->isOpened()) {
$oFile->synchronize();
$oFile->deleteFromSSD();
$iDeleted++;
} else $iIgnored++;
} else {
break;
}
}
*/
self::log("DELETED: {$iDeleted}");
self::log("IGNORED: {$iIgnored}");
self::log("SSD USAGE: ".self::GetUsage(self::$sSSDPath)."%");
}
/**
* DELETE FROM SSD
* USING ABSOLUTE VALUE of $iSSDDeleteUsageAbsolute
*/
public function deleteFromSSDAbsolute() {
$this->setLock(__FUNCTION__.'.lock');
if($this->isLock()) {
self::log("Process has already started.");
return;
}
$iDeleted = 0;
$iIgnored = 0;
/*
* Get megastorages sorted by usage desc,
*/
$aMegaStorages = $this->getMegaStorages();
foreach ($aMegaStorages as &$sMegaStorage) {
/*
* Get files in current megastorage
*/
$aFileList = $this->getFileList('/'.$sMegaStorage);
if (empty($aFileList)) {
self::log("NO FILES FOUND in {$sMegaStorage}");
continue;
}
$aFileList = array_map(
create_function('$v', '
$oFile = new VserverFile(trim($v));
return $oFile;
'),
$aFileList
);
/*
* Delete files until appropriate usage
*/
$iFreeSpace = self::GetFreeSpace('/'.$sMegaStorage);
foreach ($aFileList as &$oFile) {
self::Log($sMegaStorage." ".(round($iFreeSpace/1024/1024/1024,2))." G");
if ($iFreeSpace < self::$iSSDDeleteUsageAbsolute) {
if (!$oFile->isOpened()) {
$iFreeSpace += $oFile->getSize();
$oFile->synchronize();
$oFile->deleteFromSSD();
$iDeleted++;
} else $iIgnored++;
} else {
break;
}
}
}
self::log("DELETED: {$iDeleted}");
self::log("IGNORED: {$iIgnored}");
self::log("FREE SPACE: ".(round($iFreeSpace/1024/1024/1024,2))." G");
}
/**
*
* Get Identical files on storages
*/
public function getIdentical() {
$this->setLock(__FUNCTION__.'.lock');
if($this->isLock()) {
self::log("Process has already started.");
return;
}
$aStorages = $this->getStorages();
foreach ($aStorages as &$sStorage) {
$sDir = "/{$sStorage}/".self::$sHTTPFolder;
$aList[$sStorage] = $this->getFileList($sDir,array('flv'), "grep -Eo '".self::$sHTTPFolder.".*$'");
}
$iStorages = sizeof($aList);
for ($i=0; $i<$iStorages; $i++) {
reset($aList);
$sPrimaryStorage = key($aList);
$aPrimaryFiles = array_shift($aList);
foreach($aList as $sSecondaryStorage=>&$aSecondaryFiles) {
self::log("{$sPrimaryStorage} <-- {$sSecondaryStorage}");
//array of identical files
$aIdentical = array_intersect($aPrimaryFiles, $aSecondaryFiles);
if (!empty($aIdentical)) {
// get sizes
foreach ($aIdentical as $sFile) {
$iPrimaryPath = "/{$sPrimaryStorage}/".$sFile;
$iPrimarySize = filesize($iPrimaryPath);
$iSecondaryPath = "/{$sSecondaryStorage}/".$sFile;
$iSecondarySize = filesize($iSecondaryPath);
self::log("| {$iPrimaryPath} <-- {$iPrimarySize}");
self::log("| {$iSecondaryPath} <-- {$iSecondarySize}");
// delete if sizes are identical
if ($iPrimarySize == $iSecondarySize) self::Delete($iSecondaryPath);
// if any have null size
else if ($iPrimarySize * $iSecondarySize) continue;
else if (filectime($iPrimarySize)>filectime($iSecondaryPath)) self::Delete($iSecondaryPath);
else if (filectime($iSecondaryPath)>filectime($iPrimarySize)) self::Delete($iPrimarySize);
}
}
}
}
//echo "<pre>";
//print_r(array_intersect($aPrimaryFiles, $aSecondaryFiles));
//echo "</pre>";
}
/**
* Ñîçäàåò áëîêèðîâêó íà ïðîöåññ
*/
public function setLock($sLockFile=null) {
if(!empty($sLockFile)) {
$this->oLockFile=fopen($sLockFile,'a');
}
}
/**
* Ïðîâåðÿåò óíèêàëüíîñòü ñîçäàâàåìîãî ïðîöåññà
*/
public function isLock() {
return ($this->oLockFile && !flock($this->oLockFile, LOCK_EX|LOCK_NB));
}
/**
* Ñíèìàåò áëîêèðîâêó íà ïîâòîðíûé ïðîöåññ
*/
public function unsetLock() {
return ($this->oLockFile && #flock($this->oLockFile, LOCK_UN));
}
public function __construct() {
self::$iTimeStart = microtime(true);
}
public function __destruct() {
self::$iTimeEnd = microtime(true);
$iTimeExecution = round(self::$iTimeEnd - self::$iTimeStart,3);
$iUsageMem = memory_get_usage(true)/1024/1024; //Mb
$iUsageMemPeak = memory_get_peak_usage(true)/1024/1024; //Mb
self::log("Execution time: {$iTimeExecution} s");
self::log("Memory Usage: {$iUsageMem} Mb");
self::log("Memory Peak Usage: {$iUsageMemPeak} Mb");
$this->unsetLock();
}
/**
* Class autoloader
*
* #param unknown_type $sClassName
*/
public static function autoload($sClassName) {
require_once("{$sClassName}.class.php");
}
}
spl_autoload_register(array('Vserver','autoload'));
?>
Since array_map complains about $aOpenFiles not being an array you might want to take a look at that variable.
public function getOpenFiles($aExt=array()) {
$aOpenFiles = self::GetList(self::$sLogOpenFiles);
if ( !is_array($aOpenFiles) ) {
var_dump($aOpenFiles);
die('not an array');
}
$aOpenFiles = array_map( ...
quote:
static public function GetList($sLogPath) {
if ($sList = self::GetLog($sLogPath)) {
return explode(PHP_EOL,trim($sList));
}
}
... and if $sList evaluates to false (which may very well happen, since GetLog returns false on some conditions) this function returns nothing.
You have to check for that condition somewhere. Where depends on how you want the script to react on what condition. e.g.
static public function GetList($sLogPath) {
if ($sList = self::GetLog($sLogPath)) {
return explode(PHP_EOL,trim($sList));
}
return array();
}
would "fix" the error, but if that's feasible is another question; it may only "hide" a symptom - not the underlying problem. Must there be a log file? Must GetList(GetLog()) return a (non-empty) array? and so on and on....