how to get an uploaded file path in moodle - php

I created a new activity and i uploaded a file correctly within it but when i used
$url = moodle_url::make_pluginfile_url($file->contextid, $file->component, $file->filearea, $file->itemid,$file->filepath, $file->filename);
to get the link the result is : Sorry, the requested file could not be found
I searched an I find that I have to add a pluginfile function in my lib and this is my function :
function testnew_pluginfile($course, $cm, $context, $component, $filearea, $itemid, $path, $filename) {
global $CFG, $DB;
require_course_login($course, true, $cm);
$fullpath = "/{$context->id}/$component/$filearea/$itemid/$path/$filename";
$fs = get_file_storage();
if (!$file = $fs->get_file_by_hash(sha1($fullpath))) {
return false;
}
send_stored_file($file, 0, 0, false);
}

The problem is the context id didn't came true. so I added my add_instance function to add a new context id in mdl_files table. This is my function:
function testnew_add_instance($data){
global $DB;
$cmid = $data->coursemodule;
$data->timemodified =time();
$data->id = $DB->insert_record('testnew', $data);
$DB->set_field('course_modules', 'instance', $data->id, array('id'=>$cmid));
$fs = get_file_storage();
$draftitemid = $data->type;
$context = context_module::instance($cmid);
file_save_draft_area_files($draftitemid, $context->id, 'mod_testnew', 'content', 0);
$files = $fs->get_area_files($context->id, 'mod_testnew', 'content', 0, 'sortorder', false);
if (count($files) == 1) {
// only one file attached, set it as main file automatically
$file = reset($files);
file_set_sortorder($context->id, 'mod_testnew', 'content', 0, $file->get_filepath(), $file->get_filename(), 1);
}
return $data->id;
}

Related

Pass global variable into function not working

I am trying to use allow my custom API endpoint to upload files to a custom directory based on information sent in the request body. It is coming through fine but I am not getting it to pass into the directory properly. I have tried getting the studentid from the request body and then calling that as a global in my function but it is not working.
add_filter("wcra_upload_callback", "wcra_upload_callback_handler");
function wcra_upload_callback_handler($request) {
if (!function_exists('wp_handle_upload')) {
require_once(ABSPATH.'wp-admin/includes/file.php');
}
$studentid = $request['studentid'];
function studentresultsdir($dir) {
global $studentid;
$mydir = 'https://example.com/wp-content/uploads/studentresults/';
$dir['path'] = $mydir;
$dir['url'] = $mydir;
$dir['subdir'] = $studentid;
var_dump($dir);
return $dir;
}
add_filter("upload_dir", "studentresultsdir");
$uploadedfile = $_FILES['file'];
$upload_overrides = array('test_form' => false);
$movefile = wp_handle_upload($uploadedfile, $upload_overrides);
if ($movefile && !isset($movefile['error'])) {
echo __('File is valid, and was successfully uploaded.', 'textdomain')."\n";
var_dump($movefile);
} else {
echo $movefile['error'];
}
remove_filter("upload_dir", "studentresultsdir");
}
My var_dump of $dir is giving me an empty subdirectory. I think this is the cause of my "unable to create directory" error too but need to work this step out first.
Just wanted to add that I will be adding authentication checks once I get this working.
I managed to solve this particular error by moving the global variable outside of all functions.
add_filter("wcra_upload_callback", "wcra_upload_callback_handler");
$studentid = '';
function wcra_upload_callback_handler($request) {
if (!function_exists('wp_handle_upload')) {
require_once(ABSPATH.'wp-admin/includes/file.php');
}
global $studentid;
$studentid = $request['studentid'];
function studentresultsdir($dir) {
global $studentid;
$mydir = 'https://example.com/wp-content/uploads/studentresults/';
$dir['path'] = $mydir;
$dir['url'] = $mydir;
$dir['subdir'] = '/'.$studentid;
var_dump($dir);
return $dir;
}
add_filter("upload_dir", "studentresultsdir");
$uploadedfile = $_FILES['file'];
$upload_overrides = array('test_form' => false);
$movefile = wp_handle_upload($uploadedfile, $upload_overrides);
if ($movefile && !isset($movefile['error'])) {
echo __('File is valid, and was successfully uploaded.', 'textdomain')."\n";
var_dump($movefile);
} else {
echo $movefile['error'];
}
remove_filter("upload_dir", "studentresultsdir");
}

WordPress Plugin - Notice: Undefined index error

I'm playing around with a plugin that's a little out of date and trying to get it back up to standard but I've hit a brick wall. On line #25 of the php script below, it's throwing a Notice: Undefined index: zip_path error for if($entry['zip_path']){.
What's even more strange is that it's working on a couple of my domains but not on others. It might be worthwhile adding that the 'other' websites are hosted on external servers to the one I've been testing it on.
Can anyone provide some insight into why I'm receiving this Undefined index error?
<?php defined('ABSPATH') or die("No direct access allowed.");
require_once __DIR__ . '/vendor/autoload.php';
if (class_exists("GFForms") && !class_exists("GFBulkDownload")) {
class GFBulkDownload {
protected $name = 'Gravity Forms Bulk Download';
protected $version = '1.0';
public function __construct() {
add_action("admin_enqueue_scripts", array($this, 'addStyles'));
add_action("gform_entry_created", array($this, 'afterSubmission'), 1, 2);
add_action("gform_pre_submission_filter", array($this, 'preSubmissionFilter'), 10, 1);
add_action("gform_entries_column_filter", array($this, 'change_column_data'), 10, 5);
add_filter('gform_custom_merge_tags', array($this, 'custom_merge_tags'), 10, 4);
add_filter('gform_replace_merge_tags', array($this, 'replace_download_link'), 10, 7);
add_action("gform_entry_detail", array($this, 'addMetaToDetails'), 10, 2);
add_filter('gform_notification', array($this, 'before_email'), 10, 3);
}
function before_email( $notification, $form, $entry ) {
$site = trailingslashit(get_bloginfo('url'));
if($entry['zip_path']){
$url = $site.$entry['zip_path'];
$notification['message'] .= "\n\n <a href='{$url}' >Download All Files in Zip</a>";
}
return $notification;
}
public function addStyles(){
wp_register_style('gform_bulk_download_css', plugin_dir_url(__FILE__).'assets/css/style.css');
wp_enqueue_style('gform_bulk_download_css');
}
public function addScripts(){
}
function addMetaToDetails($form, $entry){
$zip = gform_get_meta($entry['id'], 'zip_path');
if($zip){
$site_url = trailingslashit(get_bloginfo('url'));
$url = $site_url.$zip;
echo "<table cellspacing='0' class='widefat fixed entry-detail-view'>
<tr>
<td colspan='2' class='entry-view-field-name' >Zip File Download Link</td>
</tr>
<tr>
<td colspan='2' class='entry-view-field-value lastrow'>
<a class='gfbd-btn' style='margin-left:0;' href='{$url}'> Download All Files Zip <i class='fa fa-download'> </i></a>
</td>
</tr>
</table>";
}
}
public function preSubmissionFilter($form) {
//Get upload path for form
$form_upload_dir = GFFormsModel::get_upload_path($form['id']);
//strip everything up to wp-content/.... so we can build a url
$form_upload_dir_formatted = stristr($form_upload_dir, 'wp-content/');
//decode json and remove slashes to get list of files
$files_for_zip = json_decode(stripslashes($_POST['gform_uploaded_files']), true);
if(!is_null($files_for_zip)){
//reset the array pointer
reset($files_for_zip);
// get the key of the first element (This is due to the format of the array )
$key = key($files_for_zip);
$zipArray = $files_for_zip[$key];
$zip = new ZipArchive();
$filename = 'files_' . md5(rand(0123456, 7890123)) . '.zip';
$file_path = trailingslashit($form_upload_dir) . $filename;
$zip->open($file_path, ZipArchive::CREATE);
foreach($zipArray as $file_info){
$zip->addFile($form_upload_dir . '/tmp/' . $file_info['temp_filename'], $file_info['uploaded_filename']);
}
$zip->close();
//Set the zip key for the $form object to the url for the zip file we created, minus the domainname so we can pass it to the entry
$form['zip'] = trailingslashit($form_upload_dir_formatted) . $filename;
}
return $form;
}
public function afterSubmission($entry, $form) {
//update the Entry with a zip_file meta field with a link to the zip file that was created.
if (isset($form['zip'])) {
gform_update_meta($entry['id'], 'zip_path', $form['zip']);
}
}
function change_column_data($value, $form_id, $field_id, $lead, $query_string) {
$form = GFFormsModel::get_form_meta($form_id);
$zip_path = gform_get_meta($lead['id'], 'zip_path');
$site_url = get_bloginfo('url');
$full_url = trailingslashit($site_url) . $zip_path;
foreach ($form['fields'] as $field) {
if ($field['type'] == 'fileupload' && $field['multipleFiles'] == "1") {
$upload_field_id = $field['id'];
}
}
if ($upload_field_id == $field_id) {
if (!empty($zip_path)) {
return $value . " <a class='gfbd-btn' href='$full_url'> Download All <i class='fa fa-download'> </i></a>";
}
}
return $value;
}
function custom_merge_tags($merge_tags, $form_id, $fields, $element_id) {
$merge_tags[] = array('label' => 'Download All Files (Zip)', 'tag' => '{download_all_files_zip}');
return $merge_tags;
}
function replace_download_link($text, $form, $entry, $url_encode, $esc_html, $nl2br, $format) {
$custom_merge_tag = '{download_all_files_zip}';
if (strpos($text, $custom_merge_tag) === false) {
return $text;
} else {
$zip_path = gform_get_meta($entry['id'], 'zip_path');
$full_url = trailingslashit(get_bloginfo('url')) . $zip_path;
return str_replace($custom_merge_tag, $full_url, $text);
}
}
}
new GFBulkDownload();
}
Thank you in advance.

Getting a fatal Error call to unidentified method Pass::_createpass()

Can someone please help. I am getting a fatal error on the following PHP script.
I am getting an error "unidentified method Pass::_createpass()" whick relates to the second last line of the code below.
<?php
$engine = Pass::start('xxxxxxxxxxxxxxxx');
$pass = $engine->createPassFromTemplate(xxxxxxxxxxxxxx);
$engine->redirectToPass($pass);
if (!function_exists('curl_init')) {
throw new Exception('Pass needs the CURL PHP extension.');
}
if (!function_exists('json_decode')) {
throw new Exception('Pass needs the JSON PHP extension.');
}
$engine = Pass::start($appKey);
$values = array(
'first' => 'John',
'last' => 'Platinum',
);
$images = array(
'thumbnail' => 'image1.jpg'
);
$pass = $engine->createPassFromTemplate(5688667418918912, $values, $images);
$passData = $engine->downloadPass($pass);
$engine->redirectToPass($pass);
class Pass
{
private $_appKey = null;
private $_endpoint = 'https://pass.center/api/v1';
private $_debug = false;
private static $_instance = null;
private static $_imageTypes = array('icon', 'logo', 'strip', 'thumbnail', 'background', 'footer');
const VERSION = '0.5';
const USER_AGENT = 'PassSDK-PHP/0.5';
public function __construct($appKey = null, $endpoint = null, $debug = false)
{
if (is_null($appKey)) {
throw new Exception('App Key required');
}
$this->_appKey = $appKey;
if ($endpoint !== null) {
$this->_endpoint = $endpoint;
}
$this->_debug = $debug;
}
public static function start($appKey = null, $endpoint = null, $debug = false)
{
if (self::$_instance == null) {
self::$_instance = new self($appKey, $endpoint, $debug);
}
return self::$_instance;
}
public function createPassFromTemplate($templateId, $values = array(), $images = array())
{
$resource = sprintf("https://xxxxxxx/api/v1/templates/names/Test/pass", $templateId);
return $this->_createPass($resource, $values, $images);
}
}
I hope someone can help me as I am not familiar with Functions PHP.
Thanks All
Rob
The function createPass is missing.
You need something like this:
/**
* Prepares the values and image for the pass and creates it
*
* #param string $resource Resource URL for the pass creation
* #param array $values Values
* #param array $images Images
* #return object Pass
*/
private function _createPass($resource, $values, $images)
{
$multipart = count($images) > 0;
if ($multipart) {
$content = array();
foreach ($images as $imageType => $image) {
$this->_addImage($image, $imageType, $content, $imageType);
}
var_dump($content);
// Write json to file for curl
$jsonPath = array_search('uri', #array_flip(stream_get_meta_data(tmpfile())));
file_put_contents($jsonPath, json_encode($values));
$content['values'] = sprintf('#%s;type=application/json', $jsonPath);
} else {
$content = $values;
}
return $this->_restCall('POST', $resource, $content, $multipart);
}
..And full script here

how to retrieve files when editing a file manager in moodle

I am currently doing an internship and I tried to make an activity module to show playlist, from video given by a filemanager. I succeed to send the video to the database but when I want to edit my module, it doesn't show any videos in the filemanager.
I read the moodle documentation about file API and I decided to use the following code (Load existing files into draft area)
:
if (empty($entry->id)) {
$entry = new stdClass;
$entry->id = null;
}
$draftitemid = file_get_submitted_draft_itemid('attachments');
file_prepare_draft_area($draftitemid, $context->id, 'mod_glossary','attachment', $entry->id,array('subdirs' => 0, 'maxbytes' => $maxbytes, 'maxfiles' => 50));
$entry->attachments = $draftitemid;
$mform->set_data($entry);
So I put the following lines in my mod_form.php :
$filemanager_options = array();
$filemanager_options['accepted_types'] = '*';
$filemanager_options['maxbytes'] = 0;
$filemanager_options['maxfiles'] = -1;
$filemanager_options['mainfile'] = true;
$mform->addElement('filemanager', 'files', get_string('selectfiles'), null, $filemanager_options);
if (empty($entry->id)) {
$entry = new stdClass;
$entry->id = null;
}
$draftitemid = file_get_submitted_draft_itemid('mymanager');
file_prepare_draft_area($draftitemid, $this->context->id, 'mod_playlist', 'content', 0,
array('subdirs'=>true));
$entry->attachments = $draftitemid;
$mform->set_data($entry);
The problem is that the file manager is still empty, and the line "$mform->set_data($entry); " makes the page to crash(blank).
Here is a template for uploading files.
In local/myplugin/upload.php
require_once(dirname(dirname(dirname(__FILE__))) . '/config.php');
require_once(dirname(__FILE__) . '/upload_form.php');
require_login();
$context = context_system::instance();
require_capability('local/myplugin:upload', $context);
$pageurl = new moodle_url('/local/myplugin/upload.php');
$heading = get_string('myupload', 'local_myplugin');
$PAGE->set_context($context);
$PAGE->set_heading(format_string($heading));
$PAGE->set_title(format_string($heading));
$PAGE->set_url('/local/myplugin/upload.php');
echo $OUTPUT->header();
echo $OUTPUT->heading($heading);
$fileoptions = array(
'maxbytes' => 0,
'maxfiles' => '1',
'subdirs' => 0,
'context' => context_system::instance()
);
$data = new stdClass();
$data = file_prepare_standard_filemanager($data, 'myfiles',
$fileoptions, context_system::instance(), 'local_myplugin', 'myfiles', 0); // 0 is the item id.
$mform = new upload_form(
null,
array(
'fileoptions' => $fileoptions,
)
);
if ($formdata = $mform->get_data()) {
// Save the file.
$data = file_postupdate_standard_filemanager($data, 'myfiles',
$fileoptions, context_system::instance(), 'local_myplugin', 'myfiles', 0);
} else {
// Display the form.
$mform->set_data($data);
$mform->display();
}
echo $OUTPUT->footer();
Then in local/myplugin/upload_form.php
defined('MOODLE_INTERNAL') || die;
require_once($CFG->libdir . '/formslib.php');
class upload_form extends moodleform {
public function definition() {
$mform =& $this->_form;
$fileoptions = $this->_customdata['fileoptions'];
$mform->addElement('filemanager', 'myfiles_filemanager',
get_string('myfiles', 'local_myplugin'), null, $fileoptions);
$this->add_action_buttons(false, get_string('save', 'local_myplugin'));
}
}
You will also need this in /local/myplugin/lib.php
function local_myplugin_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options = array()) {
if ($context->contextlevel != CONTEXT_SYSTEM) {
send_file_not_found();
}
$fs = get_file_storage();
$file = $fs->get_file($context->id, 'local_myplugin', $filearea, $args[0], '/', $args[1]);
send_stored_file($file);
}

Pass variables to other php document

I'm trying to set up a php that receives variables in the URL, and then creates a passbook pass using that information.
If I manually set up the variables, everything works, but if I use $_GET to get the data from the URL, it won't show up.
Here is my index, were we are loading the variables from the URL.
<?php
$ac = $_GET['ac'];
$af = $ac;
$log = print_r($_SERVER,1);
$log .= print_r($_POST,1);
$log .= print_r($_GET,1);
file_put_contents('./log/'.time().'.txt', $log);
if(($_POST['time'] != '')||($_GET['update'] != ''))
{
require('./passkit.php');
$Certificates = array('AppleWWDRCA' => './certs/AppleWWDRCA.pem',
'Certificate' => './certs/Certificate.p12',
'CertPassword' => 'password');
$ImageFiles = array('images/icon.png', 'images/icon#2x.png', 'images/logo.png');
$datostest = array( '1' => $af,
'2' => '5',
'3' => '6');
$data = array('./data/array.php',
'./data/json.php',
'./data/small.php',
'./data/coupon.json',
'./data/event.json',
'./data/small.json',
'./data/generic.json');
if($_GET['update'] != '')
{
$example_data = 4;
}
elseif(!is_numeric($_POST['aexample']))
{
$example_data = rand(0,6);
}
else
{
$example_data = $_POST['aexample'];
}
if($example_data < 3)
{
include($data[$example_data]);
}
else
{
$JSON = file_get_contents($data[$example_data]);
}
$TempPath = './temp/';
echoPass(createPass($Certificates, $ImageFiles, $JSON, 'passtest', $TempPath));
m_uwait(12500);
die();
}
?>
Here is the pass signing process
<?php
function PEM2DER($signature)
{
$signature = substr($signature, (strpos($signature, 'filename="smime.p7s"')+20));
return base64_decode(trim(substr($signature, 0, strpos($signature, '------'))));
}
function createPass($Certificates, $ImageFiles, $JSON, $PassName = 'pass', $TempPath = './temp/', $Debug = false)
{
//define pathes
$UniquePassId = time().hash("CRC32", $_SERVER["REMOTE_ADDR"].$_SERVER["HTTP_USER_AGENT"]);
$ManifestPath = $TempPath.$UniquePassId.'/manifest.json';
$SignaturePath = $TempPath.$UniquePassId.'/signature';
$PKPassPath = $TempPath.$UniquePassId.'/'.$PassName.'.pkpass';
//create temp dir
mkdir($TempPath.$UniquePassId, 0777, true);
//generate SHA1 hashes
$FileHashes['pass.json'] = hash("SHA1", $JSON);
foreach($ImageFiles as $ImagePath)
{
$ImageName = basename($ImagePath);
$FileHashes[strtolower($ImageName)] = hash("SHA1", file_get_contents($ImagePath));
}
//save hashes as json in temp file
$Manifest = json_encode($FileHashes);
file_put_contents($ManifestPath, $Manifest);
//load .p12 certificate
$PKCS12 = file_get_contents($Certificates['Certificate']);
$certs = array();
if(openssl_pkcs12_read($PKCS12, $certs, $Certificates['CertPassword']) == true)
{
$certdata = openssl_x509_read($certs['cert']);
$privkey = openssl_pkey_get_private($certs['pkey'], $Certificates['CertPassword']);
}
//sign file hashes with AppleWWDRCA certificate
openssl_pkcs7_sign($ManifestPath, $SignaturePath, $certdata, $privkey, array(), PKCS7_BINARY | PKCS7_DETACHED, $Certificates['AppleWWDRCA']);
$ManifestSignature = file_get_contents($SignaturePath);
$ManifestSignatureDER = PEM2DER($ManifestSignature);
//put files (and strings as files) in a zip archive
$ZIP = new ZipArchive();
$ZIP->open($PKPassPath, ZIPARCHIVE::CREATE);
$ZIP->addFromString('signature', $ManifestSignatureDER);
$ZIP->addFromString('manifest.json', $Manifest);
$ZIP->addFromString('pass.json', $JSON);
foreach($ImageFiles as $ImagePath)
{
$ImageName = basename($ImagePath);
$ZIP->addFile($ImagePath, $ImageName);
}
$ZIP->close();
//load pass data und delete temp files (if debug mode is off)
$Pass['data'] = file_get_contents($PKPassPath);
$Pass['size'] = filesize($PKPassPath);
$Pass['name'] = $PassName;
if(!$Debug)
{
unlink($TempPath.$UniquePassId.'/manifest.json');
unlink($TempPath.$UniquePassId.'/'.$PassName.'.pkpass');
unlink($TempPath.$UniquePassId.'/signature');
rmdir($TempPath.$UniquePassId);
}
return $Pass;
}
function echoPass($Pass)
{
//send http headers and zip archive content to client
header('Pragma: no-cache');
header('Content-type: application/vnd.apple.pkpass');
header('Content-length: '.$Pass['size']);
header('Content-Disposition: attachment; filename="'.$Pass['name'].'.pkpass"');
echo $Pass['data'];
}
?>
And finally, here I'm using those variables.
<?php
$PassStyle = "boardingPass";
$JSON = '{
"authenticationToken": "vxwxd7J8AlNNFPS8k0a0FfUFtq0ewzFdc",
"foregroundColor" : "rgb(255, 255, 255)",
"backgroundColor" : "rgb(27, 66, 152)",
"labelColor" : "rgb(108, 173, 223)",
"barcode": {
"format": "PKBarcodeFormatQR",
"message": "'.hash("SHA256", time().rand(0,2000000000)).'",
"messageEncoding": "iso-8859-1"
},
"description": "Random '.$PassStyle.' Demo Pass",
"foregroundColor": "rgb(251, 251, 251)",
"formatVersion": 1,
"'.$PassStyle.'": {
"primaryFields": [
{
"key": "number",
"value": "'.$datostest['1'].'"
}
]
},
"logoText": "passkit.php",
"organizationName": "Apple Inc",
"passTypeIdentifier": "pass.com.apple.demo",
"serialNumber": "8j23fm3",
"teamIdentifier": "123ABCDEFG"
}';
?>
Hope you can help. Can't understand why it works if the variable is manually assigned and it isn't if it is loaded from the URL.
Thanks
Look the code what you posted above is too much and i guess its difficult to check your problem...
According to the question i guess you are not able to access the Get values.
Let me tell you how get works...
<a href="filename.php?value='what_you_want_to_pass'">
and at your page...
$value = $_GET['value'];
this is the actual syntax, just check whether u have passed the value in your link...

Categories