PHP: Path is getting changed without any modification - php

I am setting file include path dynamically based on URI segments as below
URI is something like
http://script/profile/
code
$segments = explode( '/', $uri );
$file = end( $segments ) . '.php';
foreach ( $segments as $segment ) {
$dirs[] = $segment;
}
$include_path = rt_trailingslash_dir( root()->template_dir ) . implode( DIRECTORY_SEPARATOR, $dirs );
print_r($include_path . '/' . $file);
Output Something like this
c:/xampp/htdocs/.../template\profile\profile.php
Using that path in include
include $include_path . DIRECTORY_SEPARATOR . $file;
Output
template\profile.php
Which is wrong. It should be rather
template\profile\profile.php
I don't know what wrong I am doing..?

Related

Php ZipArchive add's extra folder

zipping some directory on the server I receive extra folder inside zip-archive under Windows and Linux.
Extra folder "3b84" is the ending of using md5(integer) function to set filename inside getExportPaths() method. If I try to make filename shorter - it makes me a zip archive where all files placed in one directory without their subdirectories like "CSS", "fonts" etc.
And one important thing why I'm using md5() - I need to paste into one directory a lot of zip archives. So their name should be unique.
How to fix this and remove such extra folder with a name like "3b84"?
public function actionExportdocument($id)
{
$model = Order::findOne(['id' => $id, 'user_id' => Yii::$app->user->getId()]);
if (!$model) {
throw new BadRequestHttpException('Export not found.');
}
$paths = Order::getExportPaths($model->id, $model->design->path);
$prepareFiles = Order::prepareFiles($paths, $model);
$zip = new ZipArchive();
$zip->open($paths['exportRoot'] . DIRECTORY_SEPARATOR . $paths['exportFile'],
ZipArchive::CREATE | ZipArchive::OVERWRITE);
$files = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($paths['exportPath']),
RecursiveIteratorIterator::LEAVES_ONLY
);
foreach ($files as $name => $file)
{
// Skip directories (they would be added automatically)
if (!$file->isDir())
{
$filePath = $file->getRealPath();
$relativePath = substr($filePath, strlen($paths['designPath']) + 1);
$zip->addFile($filePath, $relativePath);
}
}
$zip->close();
FileHelper::sendFile($paths['exportRoot'] . DIRECTORY_SEPARATOR . $paths['exportFile'], 'script.zip');
}
Order class contains:
public static function getExportPaths($modelId, $designPath)
{
$paths['orderIdHash'] = md5($modelId);
$paths['designPath'] = \Yii::getAlias('#app') . DIRECTORY_SEPARATOR . 'designs' . DIRECTORY_SEPARATOR . $designPath;
$paths['exportRoot'] = \Yii::getAlias('#webroot') . DIRECTORY_SEPARATOR . 'export-document';
$paths['exportPath'] = $paths['exportRoot'] . DIRECTORY_SEPARATOR . $paths['orderIdHash'];
$paths['exportFile'] = $paths['orderIdHash'] . '.zip';
return $paths;
}
public static function prepareFiles($paths, $model)
{
$exportDir = \Yii::getAlias('#webroot') . DIRECTORY_SEPARATOR . 'export-document';
if (!is_dir($exportDir)) {
mkdir($exportDir);
}
FileHelper::deleteDirectory($paths['exportPath']);
FileHelper::copyRecursive($paths['designPath'], $paths['exportPath']);
$content = '';
foreach ($model->orderTemplates as $template) {
$content .= $template->value;
}
$str = file_get_contents($paths['exportPath'] . DIRECTORY_SEPARATOR . 'index.html');
$str = str_replace("{{CONTENT}}", $content, $str);
file_put_contents($paths['exportPath'] . DIRECTORY_SEPARATOR . 'index.html', $str);
}
If I've read your question correctly; you wish to remove folders like /3b84/ from being generated.
Look inside your Order class:
public static function getExportPaths($modelId, $designPath)
{
$paths['orderIdHash'] = md5($modelId);
$paths['designPath'] = \Yii::getAlias('#app') . DIRECTORY_SEPARATOR . 'designs' . DIRECTORY_SEPARATOR . $designPath;
$paths['exportRoot'] = \Yii::getAlias('#webroot') . DIRECTORY_SEPARATOR . 'export-document';
$paths['exportPath'] = $paths['exportRoot'] . DIRECTORY_SEPARATOR . $paths['orderIdHash'];
$paths['exportFile'] = $paths['orderIdHash'] . '.zip';
return $paths;
}
See $paths['exportPath'] = $paths['exportRoot'] . DIRECTORY_SEPARATOR . $paths['orderIdHash']; ?
Remove that and you your new path will no longer have folders like /3b84/.
The problem was that I've specified wrong $relativePath.
This string was incorrect
$relativePath = substr($filePath, strlen($paths['designPath']) + 1);
And instead of it
$relativePath = substr($filePath, strlen($paths['exportPath']) + 1);

How to get path of twig template

I'm using two twig template paths found in this question How do I specify two locations for Twig templates?
$template = isset($config->template) ? $config->template : 'default';
$templates_dir = $root . 'templates' . DIRECTORY_SEPARATOR;
if (isset($config->template) && $config->template != 'default') {
$template = array($templates_dir . $config->template, $templates_dir . 'default');
} else {
$template = $templates_dir . 'default';
}
$loader = new Twig_Loader_Filesystem($template);
and I have code like this:
function render($request, $page, $data = array()) {
global $twig, $config;
$template = isset($config->template) ? $config->template : 'default';
$base = baseURI($request);
return $twig->render($page, array_merge(array(
"path" => $base . '/templates/' . $template,
"root" => $base
), $data));
}
and what I need is to get path of the template so I can use it as 'path' variable (so I can use current path for assets like "{{path}}/img/foo.png").
By searching source code I found solution in one of the test file:
$loader->getSourceContext($page)->getPath();
so if you want to have a path you need to remove template name:
$page = 'admin.html';
$path = $loader->getSourceContext($page)->getPath();
$path = preg_replace('%/'.$page.'$%', '', $path);
and if you want to get relative path you can use:
preg_replace("%" . __DIR__ . "%", "", $path);
You can wrap this in a function:
function template_path($page) {
global $loader;
$path = preg_replace("%" . __DIR__ . "%", "", $loader->getSourceContext($page)->getPath());
return preg_replace('%/'.$page.'$%', '', $path);
}

How do i find root url in php similar to server.mappath in .net

i have a page where i need to pass multiple arguments via the url
i need to get the relative root path of the public_html folder .
I tried some of the functions
$path=$_SERVER['DOCUMENT_ROOT'];
echo __FILE__;
$docRoot = $_SERVER['DOCUMENT_ROOT'];
echo "<br>";
$thisFile = str_replace('\\', '/', __FILE__);
$webRoot = str_replace(array($docRoot, 'library/config.php'), '', $thisFile);
$srvRoot = str_replace('library/config.php', '', $thisFile);
echo $docRoot."<br>".$webRoot."<br>".$srvRoot;
$p=getcwd();
echo "<br>".dirname ( $p );
$my_folder = dirname( realpath( __FILE__ ) ) ;
echo "<br>".$my_folder;
echo "<br>".basename($_SERVER["SCRIPT_FILENAME"], '.php');
i get the path as "/home/elitenua/public_html/gallitest/index.php"
i want the path as "/gallitest/index.php"
Please help.
Thanks in advance.
$basedir = $_SERVER['PHP_SELF'];
Thats what you are searching for.

Moving files into directory in foreach loop?

i've no idea how to do that and need your help!
i have an array of filenames called $bundle. (file_one.jpg, file_two.pdf, file_three.etc)
and i have the name of the folder stored in $folder. (my_directory)
i now would like to move all the files stored in $bundle to move to the directory $folder.
how can i do that?
//print count($bundle); //(file_one.jpg, file_two.pdf, file_three.jpg)
$folder = $folder = PATH . '/' . my_directory;
foreach ($bundle as $value) {
//rename(PATH.'/'.$value, $folder . '/' . $value);
}
just so it's not confusing: PATH just stores the local file-path im using for my project. in my case it's just the folder i'm working in-so it's "files".
i have no idea which method i have to use for this and how i could solve that!
thank you for your help!
The code given by you should work with minor changes:
$folder = PATH . '/' . 'my_directory'; // enclose my_directory in quotes.
foreach ($bundle as $value) {
$old = PATH.'/'.$value, $folder;
$new = $folder . '/' . $value;
if(rename($old,$new) !== false) {
// renamed $old to $new
}else{
// rename failed.
}
}
$folder = PATH . '/' . $folder;
foreach ($bundle as $value) {
$old = PATH.'/'.$value;
$new = $folder . '/' . $value;
if(rename($old,$new) !== false) {
// renamed $old to $new
}else{
// rename failed.
}
}
Untested but should work:
function bulkMove($src, $dest) {
foreach(new GlobIterator($src) as $fileObject) {
if($fileObject->isFile()) {
rename(
$fileObject->getPathname(),
rtrim($dest, '\\/') . DIRECTORY_SEPARATOR . $fileObject->getBasename()
);
}
}
}
bulkMove('/path/to/folder/*', '/path/to/new/folder');
Could add some checks to see if the destination folder is writable. If you dont need wildcard matching, change the GlobIterator to DirectoryIterator. That would also eliminate the need for PHP5.3

Namespace Autoload works under windows, but not on Linux

I have the following php code:
index.php
<?php
spl_autoload_extensions(".php");
spl_autoload_register();
use modules\standard as std;
$handler = new std\handler();
$handler->delegate();
?>
modules\standard\handler.php
<?php
namespace modules\standard {
class handler {
function delegate(){
echo 'Hello from delegation!';
}
}
}
?>
Under Windows 7, running WAMP, the code produces the message "Hello from Delegation!" however under Linux, I get the following:
Fatal error: spl_autoload(): Class modules\standard\handler could not be loaded in /var/www/index.php on line 15
Windows is running PHP 5.3.0 under WAMP, and Linux is running the 5.3.2 dotdeb package under Ubuntu 9.10.
Is this a configuration issue on my linux box, or just a difference in the way namespaces and autoloading is handled on the different operating systems
The SPL autoloader is extremely primitive - it has no knowledge of namespaces, so it tries to load a file with \ in it's name while on Linux/Unix the path separator is / not .
Herman Radtke says he has submitted a patch :
http://www.hermanradtke.com/blog/hidden-features-with-spl_autoload-and-namespaces/
:s
I'm hoping it'll be implemented soon.
For now I use this workaround :
<?php
set_include_path( './classes/' . PATH_SEPARATOR . get_include_path() );
spl_autoload_extensions( '.php , .class.php' );
spl_autoload_register();
function linux_namespaces_autoload ( $class_name )
{
/* use if you need to lowercase first char *
$class_name = implode( DIRECTORY_SEPARATOR , array_map( 'lcfirst' , explode( '\\' , $class_name ) ) );/* else just use the following : */
$class_name = implode( DIRECTORY_SEPARATOR , explode( '\\' , $class_name ) );
static $extensions = array();
if ( empty($extensions ) )
{
$extensions = array_map( 'trim' , explode( ',' , spl_autoload_extensions() ) );
}
static $include_paths = array();
if ( empty( $include_paths ) )
{
$include_paths = explode( PATH_SEPARATOR , get_include_path() );
}
foreach ( $include_paths as $path )
{
$path .= ( DIRECTORY_SEPARATOR !== $path[ strlen( $path ) - 1 ] ) ? DIRECTORY_SEPARATOR : '';
foreach ( $extensions as $extension )
{
$file = $path . $class_name . $extension;
if ( file_exists( $file ) && is_readable( $file ) )
{
require $file;
return;
}
}
}
throw new Exception( _( 'class ' . $class_name . ' could not be found.' ) );
}
spl_autoload_register( 'linux_namespaces_autoload' , TRUE , FALSE );
?>
function __autoload($class_name) {
$paths[] = dirname(__FILE__) . "/../libs/misc/";
$paths[] = dirname(__FILE__) . "/../../libs/misc/";
$paths[] = dirname(__FILE__) . "/../../libs/helpers/";
$paths[] = dirname(__FILE__) . "/../../libs/simpleimage/";
foreach($paths as $path)
{
if(file_exists($path.strtolower($class_name).'.class.php')){
require_once($path.strtolower($class_name).'.class.php');
}
}
}
function __autoload($class_name)
{
$class_name = strtolower(str_replace('\\', DIRECTORY_SEPARATOR, $class_name));
include $class_name . '.php';
}
The srttolower is needed on Apache because it is (contrary to IIS) case sentive.
This is a common problem occurs when autoloading. The fix is to use DIRECTORY_SEPARATOR constant in the autoload function.
So your autoload function will look like following
<?php
spl_autoload_register(function($className) {
$className = str_replace("\", DIRECTORY_SEPARATOR, $className);
include_once $_SERVER['DOCUMENT_ROOT'] . '/class/' . $className . '.php';
});
If you need to learn more on namespace/class autoloading visit here
Thanks.

Categories