Moodle local plugins and save_file - moodle

I've created a working form within a local plugin and it is inserting data fine into my custom table.
What I want tyo add now is a filepicker element that upon saving the form puts the file into a specified folder.
The filep[icker itself works fine but when I save the form no file appears, the code I'm using looks like this:
$mform->save_file('lowresCh', '/my_form/', false);
I've tried various things in the 'my_form' bit, but to no avail. The rest of the form still puts its data into the custom table and I can see my file in the mdl_files table (marked as draft).
With full debugging on I can get a warning of:
Warning: copy(/my_form/): failed to open stream: Is a directory in /...../lib/filestorage/stored_file.php on line 390
I don't know if I'm approaching it incorrectly or not, any help or pointers in the right direction would be most appreciated. 
Oh and I have read the Using the File API in Moodle forms page, useful in getting me to the point I'm at, but no further.

I solved it by using the filename as the second argument in save_file() and if I prepend a directory then all of the files will be saved within my plugin in a sub directory which is perfect.
So it looks like this now:
$mform->save_file('lowresCh', 'files/'.$mform->get_new_filename('lowresCh'), false);

Related

How can I manually edit the list of recently opened files in VS Code?

I rely heavily on the File: Open Recent… command to open frequently used files, but yesterday my local Google Drive folder got moved to a new location and now I can no longer access any of the files in that folder through the Open Recent panel because the paths don't match.
The fix would be as simple as replacing "/Google Drive/" with "/Google Drive/My Drive/" but I have no idea what file contains the list of files that appears in the recently opened panel.
I'm assuming it's somewhere in ~/Library/Application Support/Code but not sure where.
I was wondering the same thing the other day and found this while searching for a solution, so I took some time to investigate it today.
It's been a a few weeks since you posted, so hopefully this will still be of help to you.
Also, I'm using Windows and I'm not familiar with macOS, but I think it should be easy enough adjust the solution.
Location of settings
Those setting are stored in the following file: %APPDATA%\Code\User\globalStorage\state.vscdb.
The file is an sqlite3 database, which is used as a key-value store.
It has a single table named ItemTable and the relevant key is history.recentlyOpenedPathsList.
The value has the following structure:
{
"entries": [
{
"folderUri": "/path/to/folder",
"label": "...",
"remoteAuthority": "..."
}
]
}
To view the current list, you can run the following command:
sqlite3.exe -readonly "%APPDATA%\Code\User\globalStorage\state.vscdb" "SELECT [value] FROM ItemTable WHERE [key] = 'history.recentlyOpenedPathsList'" | jq ".entries[].label"
Modifying the settings
Specifically, I was interested in changing the way it's displayed (the label), so I'll detail how I did that, but it should be just as easy to update the path.
Here's the Python code I used to make those edits:
import json, sqlite3
# open the db, get the value and parse it
db = sqlite3.connect('C:/Users/<username>/AppData/Roaming/Code/User/globalStorage/state.vscdb')
history_raw = db.execute("SELECT [value] FROM ItemTable WHERE [key] = 'history.recentlyOpenedPathsList'").fetchone()[0]
history = json.loads(history_raw)
# make the changes you'd like
# ...
# stringify and update
history_raw = json.dumps(history)
db.execute(f"UPDATE ItemTable SET [value] = '{history_raw}' WHERE key = 'history.recentlyOpenedPathsList'")
db.commit()
db.close()
Code references
For reference (mostly for my future self), here are the relevant source code areas.
The settings are read here.
The File->Open Recent uses those values as-is (see here).
However when using the Get Started page, the Recents area is populated here. In the Get Started, the label is presented in a slightly different way:
vscode snapshot
The folder name is the link, and the parent folder is the the text beside it.
This is done by the splitName method.
Notes
Before messing around with the settings file, it would be wise to back it up.
I'm not sure how vscode handles and caches the settings, so I think it's best to close all vscode instances before making any changes.
I haven't played around with it too much, so not sure how characters that need to be json-encoded or html-encoded will play out.
Keep in mind that there might be some state saved by other extensions, so if anything weird happens, blame it on that.
For reference, I'm using vscode 1.74.2.
Links
SQLite command-line tools
jq - command-line JSON processor

Word addin, set filename

If one starts a blank file on Word you can usually see in the top bar a name such as "Document1", "Document2" and so on.
Yet, if you attempt to open a file using the Word JS API like this:
Word.run((context) => {
context.application.createDocument(documentB64).open()
return context.sync()
})
The top bar comes out like this:
No filename is set.
To set a filename/handle(?), I tried using the code given here Office JS - Add customProperty to new document but that didn't help.
My addin is usually used in conjunction with another (VSTO) add-on and that add-on can't work properly with the documents opened by my addin and I believe the lack of a filename (/handle?) explains it to some extent.
Is there something I can do about this?
Thank you
Currently you can't do this because the newly created document is just a temporary file and not saved. can you try to call the following code to make sure the newly created file is saved?
const documentCreated = context.application.createDocument(externalDoc);
documentCreated.save();
documentCreated.open();

Why does DITA Open Toolkit PDF plugin rename image href attributes?

I'm sorry if this doesn't have enough information. I don't typically ask for help online like this.
I'm using DITA Open Toolkit 3.4 on Windows. I generated a plugin called "vcr2" using Jarno's (very excellent and helpful) PDF Plugin Generator and then made a handful of customizations. The plugin uses the pdf2 plugin as a base. When I try to use the vcr2 plugin, my images are not working. I've tracked the problem down to malformed image filenames in the image's href attribute.
For example:
In my source file (a DITA Task), the markup for one of my images looks like this:
<image href="MyRemindersChooseReminder.png"/>
If I run a transform with the pdf2 plugin, the images work fine. In the merged stage1.xml file in the Temp folder, the XML for that same image looks like this:
<image class="- topic/image " href="df2d132af27436c59c5c8c4282e112d62bec8201.png" placement="inline" xtrc="image:1;10:66" xtrf="file:/V:/Vasont/Extract/t12340879-minimal/t12340879.xml"/>
It is processed into a file Topic.fo, and looks like this:
<fo:external-graphic
 src="url('file:/V:/Vasont/Extract/t12340879-minimal/MyRemindersChooseReminder.png')"/>
Everything works fine and the image looks fine.
If I run the same file through my 'vcr2' plugin, which just calls the same pdf2 plugin with some overrides, all the images get broken:
stage1.xml
<image class="- topic/image " href="df2d132af27436c59c5c8c4282e112d62bec8201.png" placement="inline" xtrc="image:1;10:66" xtrf="file:/V:/Vasont/Extract/t12340879-minimal/t12340879.xml"/>
Topic.fo
<fo:external-graphic
 src="url('file:/V:/Vasont/Extract/t12340879-minimal/df2d132af27436c59c5c8c4282e112d62bec8201.png')"
/>
As I track this down further, it appears that somewhere in the map-reader Ant task, this filename gets changed to that cryptic string of pseudo-hexadecimal. I think later on it's supposed to be changed back or resolved to a complete URI or something.
So, the two-part question is: Why does Open Toolkit change my filenames, and what's supposed to change them back?
DITA-OT's preprocess uses hashes for temporary filenames because it allows the code to not deal with directory structures. This enables preprocess to work in so-called "map-first" mode, where it first processes all DITA map resources and only then starts to process DITA topic and image resources.
The preprocess has a step called clean-preprocess that can rewrite the temporary file names to match source resource files names. However, this rewrite operation is disabled for PDF output because the original file names are not used for anything in that output type.

Issue with a topjson object in a Meteor app built with coffeescript

Apologies for the lack of precision in the question, but I'm not completely sure which of possibly many things I'm doing wrong here.
I'm relatively new to Coffeescript and also geo applications in general, but here goes:
I've got a working (simple) Meteor (.7.0.1) application utilizing coffeescript in both client and server. The issue I'm having occurs when attempting to utilize TopoJSON encoded files to create a layer of US congressional districts. (the purpose of the app is to help highlight voter suppression in the US)
So, a few things: Typically in a non-Meteor app, I would just load the topoJSON file like so:
$.getJSON('./data/us-congress-113.json', function (data) {
var congress_geojson = topojson.feature(data, data.objects.districts);
congress_layer.addData(congress_geojson);
});
Now of course this won't work in Meteor because its not asynchronous.
One of the things that was recommended here on SO was to not worry about reading the file, and to instead change the json file to .js, and then set the contents (which are of course just an object) equal to a variable.
Here's what I did:
First, I changed the .json file to a .js file in the server directory, and added the "congress =" to the beginning of the file. It's a huge file so forgive me for omitting the whole object.
congress = {"type":"Topology",
"objects":
{"districts":
{"type":"GeometryCollection","geometries":[{"type":"Polygon"
Now here's where everything starts to give me issues:
In the server.coffee, I've created a variable like so to reference the congress object:
#congress_geojson = topojson.feature(congress, congress.objects.districts)
Notice how I'm putting the # symbol there? I've been told this allows a variable in Coffeescript to be globally scoped? I tried to also use a Meteor feature called "share" where I declare the variable as "share.congress_geojson". That led to the same issues which I will describe below.
Now in the client.coffee file, I'm trying to call this variable to load into a Leaflet map.
congress_layer = L.geoJson(null,
style:
color: "#DE0404"
weight: 2
opacity: 0.4
fillOpacity: 0.1
)
congress_layer.addData(#congress_geojson)
This isn't working, and specifically (despite attempts to find other ways, the errors I'm getting in the console are:
Exception from Deps afterFlush function: TypeError: Cannot read property 'features' of undefined
at o.GeoJSON.o.FeatureGroup.extend.addData (http://localhost:3000/packages/leaflet.js?ad7b569067d1f68c7403ea1c89a172b4cfd68d85:39:16471)
at Object.Template.map.rendered (http://localhost:3000/client/client.coffee.js?37b1cdc5945f3407f2726a5719e1459f44d1db2d:213:18)
I have no doubt that I'm missing something stupidly obvious here. Any suggestions or tips for what I'm doing completely wrong would be appreciated. Is it a case where an object globally declared in a .js file isn't available to code in a .coffee file? Maybe I'm doing something wrong on the Meteor side?
Thanks!
Edit:
So I was able to get things working by putting the .js file containing the congress object in a root /lib folder, causing the object to load first, and then calling the congress object from the client. However, I'm still wanting to know how I could simply share this object from the server? What is the "Meteor way" here?
If you are looking for the Meteor way to order the loading of files, use the Meteor.startup function and put the initialization code there. That function is the $.ready of the Meteor world, i.e., it will execute only after all your files have been successfully loaded on the client.
So in your case:
Meter.startup ->
congress_layer.addData(#congress_geojson)

Joomla template parameters and params.ini - file becomes unwritable after save

I am using wamp on Win XP SP3 and creating a Joomla template with changeable parameters.
initially the message is
The parameter file \templates\ssc_2010\params.ini is
writable!
once I make changes everything works as expected, except now i get the message:
The parameter file \templates\ssc_2010\params.ini is
unwritable!
One solution is to brows to the directory, right click the file, select properties, and uncheck read-only. Again the file is writable but once I modify the parameters again it becomes read only again. I'm quite lazy and would like to prevent this from happening again, I've notice this happening in past projects, but now I have to work a lot with parameters so it becomes quite boring doing manual labor like that :P
There is a bug in Joomla 1.5 that causes the message to be displayed.
A security feature was added that makes the template files unwritable until just before save, where they are made writable, saved, then made unwritable again.
Try to make a change, then go back and check the preview. You will see that the change was actually made.
If you want to fix the annoying unwritable message, add the following code to
administrator/components/controller.php around line 179, just after setting the FTP credentials:
$file = $client->path.DS.'templates'.DS.$template.DS.'params.ini';
// Try to make the params file writeable
if (!$ftp['enabled'] && JPath::isOwner($file) && !JPath::setPermissions($file, '0755')) {
JError::raiseNotice('SOME_ERROR_CODE', JText::_('Could not make the template parameter file writable'));
}
This will make the file writable during the edit load process, and before the file's status is posted in the template.
Then for security, in case the edit screen is closed without saving, search for the following lines:
require_once (JPATH_COMPONENT.DS.'admin.templates.html.php');
TemplatesView::editTemplate($row, $lists, $params, $option, $client, $ftp, $template);
and paste the following code just AFTER these lines but before the closing brace:
// Try to make the params file unwriteable
if (!$ftp['enabled'] && JPath::isOwner($file) && !JPath::setPermissions($file, '0555')) {
JError::raiseNotice('SOME_ERROR_CODE', JText::_('Could not make the template parameter file unwritable'));
}
That will make the file unwritable again.
This is the same code that is used in the saveTemplate() function. We are just doing it again before we display the status of the file on the edit screen. If the process fails because of your web server's configuration, you will get warning messages, BEFORE you've made a bunch of changes to your template. :)
P.S. Remember to save a copy of this file separately, so that you can redo the changes when you upgrade Joomla! (if they haven't fixed this themselves yet.)
This sounds like a user rights problem within Windows - have a look a the security permissions for the directory in which the file you are editing is located, and check that the user "IUSR_xxx" (where xxx is the name of your computer) has full control.
If this doesn't work, then can you tell us what version of Windows you are running as this may help...
Matt