-
Posts
364 -
Joined
Everything posted by hellomoto
-
delete orphaned files/images from site/assets/files
hellomoto replied to interrobang's topic in General Support
I have a script derived from this thread that used to work but now I'm trying to run it on a dev branch project and I get this error message: Here's the code: <pre><?php ini_set('max_execution_time', 60 * 5); // 5 minutes, increase as needed include("./index.php"); $dir = new DirectoryIterator(wire('config')->paths->files); foreach ($dir as $file) { if ($file->isDot() || !$file->isDir()) { continue; } $id = $file->getFilename(); if (!ctype_digit("$id")) { continue; } $page = wire('pages')->get((int) $id); if (!$page->id) { echo "Orphaned directory: " . wire('config')->urls->files . "$id/" . $file->getBasename() . "\n"; continue; } // determine which files are valid for the page $valid = array(); foreach ($page->template->fieldgroup as $field) { if ($field->type instanceof FieldtypeFile) { foreach ($page->get($field->name) as $file) { $valid[] = $file->basename; if ($field->type instanceof FieldtypeImage) { foreach ($file->getVariations() as $f) { //$valid[] = $f->basename; } } // keep thumbnails: /* if ($field->type instanceof FieldtypeCropImage) { $crops = $field->getArray(); $crops = $crops['thumbSetting']; $crops_a = explode("\n", $crops); // ie. thumbname,200,200 (name,width,height) foreach ($crops_a as $crop) { $crop = explode(",", $crop); $prefix = wire('sanitizer')->name($crop[0]); $valid[] = $prefix . "_" . $file->basename; } }*/ } } } // now find all the files present on the page // identify those that are not part of our $valid array $d = new DirectoryIterator($page->filesManager->path); foreach ($d as $f) { if ($f->isDot() || !$f->isFile()) { continue; } if (!in_array($f->getFilename(), $valid)) { echo "Orphaned file: " . wire('config')->urls->files . "$id/" . $f->getBasename() . "\n"; // unlink($f->getPathname()); } } wire('pages')->uncache($page); // just in case we need the memory } I tried preceding the wire in mention with a $ and also with Processwire/ respectively. Processwire/wire returns this: and $wire : Why is this? -
Changing file/dir permissions on OSX XAMPP
hellomoto replied to hellomoto's topic in Getting Started
I got the site to load finally, by replacing the htaccess with a fresh copy -- but now none of the assets/styles are being loaded, as $config->urls->root points to localhost instead of localhost/mysite, where PW is installed. How do I fix this? And why is all this only happening now... I've never run into these permissions or migrations problems before, despite the setup being relatively new, I've managed both so far, up until now. I can't think of anything I did that might have had this effect. Maybe I'll switch to AMPPS or MAMP or something. -
Changing file/dir permissions on OSX XAMPP
hellomoto replied to hellomoto's topic in Getting Started
Thanks, but it's not the same. Also worthy of note is that if I try to go to /admin or /xxx, /*, the filename of the empty download matches whatever that is. -
Changing file/dir permissions on OSX XAMPP
hellomoto replied to hellomoto's topic in Getting Started
I'm doing this because I lost my backups and am trying to copy a site from its live server online onto my localhost. But when I copy over the files, import the db and change the connection settings in the site config, then try to access it, it just downloads a blank file called "download" (no extension). That's it, that's all. What could be the problem? -
After a full day of failed attempts at setting up a pro, Vagrant-based development environment on my Macbook, I settled for good old XAMPP. Some sites were migrated over successfully, as well as a fresh PW project installed (dev branch). However, for some reason now, as I try installing another fresh copy (dev or stable), I get this error: File system is not writable by this installer. So I rename the site profile manually, but then I need to fix the permissions for site/config.php and site/assets/. How exactly do I do this? I've tried chmod in Terminal, and messing around in the file/directory Get Info window, although I'm not sure which user or group to edit. Either way, I'm not getting anywhere. Please help. Thanks.
-
Apparently it's due to some customizing I did to ProcessChangelog, somehow... I only tried to add views to the records...
-
If attempted on pages admin view, simply loads forever; if on page edit, reloads the page editor URL as blank. On dev branch
-
I was able to add pageviews before and now on a fresh install of PW3 without the previous successful attempt to draw from, here's what I have for ProcessChangelogHooks.module: Somehow with this I'm unable to publish or unpublish pages; if attempted on the pages admin view it just loads forever, on the page editor it reloads the editor blank and doesn't work.
-
I have these fields: availability, date_sold, price_sold. availability is a page field. The parent page of the selectable pages is also called availability. date_sold and price_sold are both set to Visibility: Open, with Show This Field Only If set to availability.title=sold, charter=0 (charter is a checkbox). The charter inputfield dependency works, but not the availability. I've tried availability=sold and availability.name=sold as well. Am I missing something? Please help, thanks much.
-
Damn, not sure how I feel about these results... Okay so of course, the specs: PW 2.6.1. Uploads do work on desktop no problem. I have not tried on an iPhone, don't have access to one, but on my phone I get the following error: song title • song title is a invalid extension, please use one of: mp3, zip That's in Chrome, on Android 5.0 (Samsung Galaxy S5 Active). On my friend's phone (who this is for) the Choose File button doesn't even do anything. He's using the Internet app on Android 4.4.2 (Alcatel OneTouch Fierce). I don't know what else I can do to troubleshoot this... I tried unchecking the decompress zip files option, not thinking it would do anything and it was indeed no help. Any ideas are very much welcome and appreciated! We're traveling and he's got unlimited data on his phone, so mobile upload capability would greatly help given our situation. The screen where I select songs from when clicking Choose File doesn't show their extensions, but when I go to browse my files on my phone and go to the audio ones, all the same files are there listed with the mp3 extension.
- 8 replies
-
- admin
- file upload
-
(and 2 more)
Tagged with:
-
I'm surprised there've been no replies... but more surprised that I can't find anything else on this topic, I would think this would concern people. Bumpin
- 8 replies
-
- admin
- file upload
-
(and 2 more)
Tagged with:
-
I can't find anything about this in the forums or anything, but I have a file field that accepts mp3 files. Trying to upload from an Android phone (I've tried from two) the files aren't accepted, it says they must be mp3 files, but they are, so it's not reading the file extensions I guess... The error names the file name without the extension saying it's missing the extension. Has anyone come across this? Thanks.
- 8 replies
-
- admin
- file upload
-
(and 2 more)
Tagged with:
-
My Small Module: class CalendarEventsCustom extends WireData implements Module { /** * getModuleInfo is a module required by all modules to tell ProcessWire about them * * @return array * */ public static function getModuleInfo() { return array( 'title' => 'Calendar Events Custom', 'version' => 1, 'summary' => 'Renames subevents', 'href' => '', 'singular' => true, 'autoload' => true, 'icon' => '', ); } public function init() { $this->pages->addHookBefore('save', $this, 'nameEvents'); } protected function nameEvents($event) { $page = $event->arguments[0]; $sanitizer = wire('sanitizer'); if($page->template == 'calendar-event') $page->name = wireDate('Y-m-d',$page->calendar_event_start) . '/' . $sanitizer->pageName($page->title, true); elseif($page->template == 'calendar-event_instance') $page->name = wireDate('Y-m-d',$page->calendar_event_start); // if calendar_start_date != rrule don't publish } } It'll probably be of no help to you, and anyway as it turns out, of course I was just confused and checking the wrong parent template's settings. Name format for children was not set where it was supposed to be. If you want to disable a certain notification then it sounds to me like you're on the right track... What message are you trying to get rid of?
- 4 replies
-
- 1
-
- templates
- name generation
-
(and 1 more)
Tagged with:
-
For my event template I have tried setting the Name format for children as title and date, respectively, as those are the only two I've ever gotten to work with that. So I do have a small module that renames them before save, to Y-m-d-title, but I can't manage to get adding an event from the admin the standard way to skip the Page Add step with the Title and Name generation. Not only that but it always displays the warnings for Name Already taken, which I don't want, as they're organized by date... Admin users don't need to see "The name entered is already in use. If you do not modify it, the name will be made unique automatically after you save.". How can I bypass this? Thanks.
- 4 replies
-
- templates
- name generation
-
(and 1 more)
Tagged with:
-
I am trying to build on lindquist's Calendar module just to get a working demo of some additional features I would eventually like to somehow implement in a more solid way, such as overriding the default info for a recurring event for some instances. Here is my events template: <?php $scriptsHead[] = $config->urls->templates."js/moment.min.js"; $scriptsHead[] = $config->urls->templates."js/fullcalendar.min.js"; $styles[] = $config->urls->templates."css/fullcalendar.min.css"; $content .= '<div id="calendar" style="width:100%"></div>'; $calendar = wire('modules')->getModule('Calendar'); // get current/upcoming events -1:+6 months $start = new DateTime(); $until = new DateTime(); $start->sub(new DateInterval('P1M')); $until->add(new DateInterval('P6M')); $events = $calendar->expandEvents($start, $until); //$start = strtotime($start); $start = $start->format('Y-m-d H:i'); $until = $until->format('Y-m-d H:i'); function eventsToJSON($events, $start, $until) { $items = array(); $ids = array(); $idx = 0; foreach($events as $event) { $pages = wire('pages'); $eid = $pages->get($event->event->id); $allday = (bool)$eid->calendar_event_allday; $recurs = (bool)$eid->calendar_event_recurs; if($eid->children("calendar_event_start={$start}")) { $start = wireDate($event->start->format('Y-m-d H:i')); if($eid->children("calendar_event_start={$start}")) { $subevent = $eid->children("calendar_event_start={$start}"); //echo "same same {$subevent->id} {$subevent->title} {$eid->title}"; } } // translate events from some source to a format recognizable by fullCalendar $addItem = array( 'id' => $event->event->id, 'title' => $event->event->title, 'allDay' => $allday, 'start' => wireDate($event->start->format('Y-m-d H:i')),//calendar_event_start), 'end' => wireDate($event->end->format('Y-m-d H:i')), //'url' => "./$event[id]", // event ID is the url segment 'url' => $event->event->url, ); $items[] = $addItem; //$n = 0; $c = 0; if($eid->hasChildren() && !in_array($eid->id, $ids)) { foreach($eid->children() as $i) { $items[] = array( 'id' => $i->id, 'title' => "{$i->parent->title}: {$i->title}", 'start' => wireDate('Y-m-d', $i->calendar_event_start), 'url' => $i->url, ); $items[$idx]['title'] = "{$i->parent->title}: {$i->title}"; } //echo $n . ' ' . $c; } $ids[] = $eid->id; //$n++; $c++; /* if($event->calendar_event_recurs == true) { echo $event->calendar_event_rrule; }*/ } //print_r($items); //$idx++; return json_encode($items); } $eventsJson = eventsToJSON($events, $start, $until); //echo '<br><br>'.$eventsJson; $content .= <<<EOT <script> $(document).ready(function() { /* date store today date. d store today date. m store current month. y store current year. */ var date = new Date(); var d = date.getDate(); var m = date.getMonth(); var y = date.getFullYear(); /* Initialize fullCalendar and store into variable. Why in variable? Because doing so we can use it inside other function. In order to modify its option later. */ var calendar = $('#calendar').fullCalendar( { /* header option will define our calendar header. left define what will be at left position in calendar center define what will be at center position in calendar right define what will be at right position in calendar */ header: { left: 'prev,next today', center: 'title', right: 'month,agendaWeek,agendaDay' }, /* defaultView option used to define which view to show by default, for example we have used agendaWeek. */ defaultView: 'month', /* selectable:true will enable user to select datetime slot selectHelper will add helpers for selectable. */ selectable: true, selectHelper: true, /* when user select timeslot this option code will execute. It has three arguments. Start,end and allDay. Start means starting time of event. End means ending time of event. allDay means if events is for entire day or not. */ select: function(start, end, allDay) { /* after selection user will be promted for enter title for event. */ var title = prompt('Event Title:'); /* if title is enterd calendar will add title and event into fullCalendar. */ if (title) { calendar.fullCalendar('renderEvent', { title: title, start: start, end: end, allDay: allDay }, false // make the event "stick" ); } calendar.fullCalendar('unselect'); }, /* editable: true allow user to edit events. */ editable: false, /* events is the main option for calendar. for demo we have added predefined events in json object. */ events: {$eventsJson} }); }); </script> EOT; The calendar-event template is generated by the module; I added a child template, calendar-event_instance. So the above outputs the calendar and its events, but any recurring event instance with info input appears twice: regular, e.g., 6p Game Night, and preceded with an all-day event, Game Night: Monopoly. What I want is to replace the event recurrence's title and URL with the one for that instance when one exists.
-
Previous & Next navigation links in page editor?
hellomoto replied to hellomoto's topic in API & Templates
Both of those work, but I'd still like to be able to put it in as part of the page edit template itself more so that they appear above and below the fields in any tab. Also, AdminSaveActions doesn't have an option to edit previous page, and for whatever action you choose to carry out, you need to save the page. Maybe you want to browse through in either direction without saving your changes in 1 click instead of 2+. -
I have a template that is used for one page, "tracks" (tpl & pg name). Under the Access tab the "uploader" role is checked for View Pages, Edit Pages, and Add Children. I even added a page-edit-tracks_upload permission via Page Edit Field Permission module which is enabled for "uploader" and yet when I try to edit the tracks page as a regular uploader, I get "ProcessWire: You don't have access to edit", "The process returned no content." The uploader in question did not create the page but I want any uploader to be able to edit this one field of the page (none others exist besides the title and settings fields). How can I achieve that?
-
Deleting file field's files via API not working or timing out
hellomoto replied to hellomoto's topic in General Support
This worked protected function addNewTracks($event) { $page = $event->arguments[0]; $pages = wire('pages'); if($page->template == 'tracks' && count($page->tracks_upload) > 0) { foreach($page->tracks_upload as $t) { $basename = str_replace(".{$t->ext}",'',$t->name); $p = new Page; $p->parent = $pages->get('/tracks/'); $p->template = 'track'; $p->title = $basename; $p->addStatus(Page::statusUnpublished)->save(); $p->audio->add($t->filename); $p->save(); $p->name = $p->id; $p->save(); $this->message("Added new track {$p->title} by {$p->createdUser->name}"); } $page->tracks_upload->removeAll(); $page->save(); } } -
<?php class ProcessTracksterMultiUpload extends WireData implements Module { /** * getModuleInfo is a module required by all modules to tell ProcessWire about them * * @return array * */ public static function getModuleInfo() { return array( 'title' => 'Process Trackster Multi-Upload', 'version' => 1, 'summary' => 'Creates a new page for each individual track', 'href' => '', 'singular' => true, 'autoload' => true, 'icon' => '', ); } /** * Initialize the module * * ProcessWire calls this when the module is loaded. For 'autoload' modules, this will be called * when ProcessWire's API is ready. As a result, this is a good place to attach hooks. * */ public function init() { $this->pages->addHookAfter('save', $this, 'addNewTracks'); } /** * Adds tracks * */ protected function addNewTracks($event) { $page = $event->arguments[0]; $pages = wire('pages'); if($page->template != 'tracks') return; foreach($page->tracks_upload as $t) { $basename = str_replace(".{$t->ext}",'',$t->name); $p = new Page; $p->parent = $pages->get('/tracks/'); $p->template = 'track'; $p->title = $basename; $p->name = $p->id; $p->addStatus(Page::statusUnpublished)->save(); $p->audio->add($t->filename); $p->save(); $this->message("Added new track {$p->name} by {$p->createdUser}"); //wire('pages')->get(1014)->tracks_upload->delete($t->filename); //$deleted = $t->name; //$files->delete($t); $this->message("Deleted temporary file $$t->filename"); //$this->message("new $newname"); } $pages->get($page->id)->tracks_upload->deleteAll(); $pages->get($page->id)->save(); //$page->tracks_upload->removeAll()->save(); //$thisPage = $pages->get($page->id); //$thisPage->save(); //$page->tracks_upload->deleteAll(); //$page->save(); } } I've tried $page->tracks_upload->deleteAll(), removeAll(), $page->delete($t), $page->delete($t->name) ($page ones in the foreach loop), all kinds of things. Nothing seems to work. Pages are created fine and all, I just need these files deleted too.
-
<?php class ProcessTracksterMultiUpload extends WireData implements Module { /** * getModuleInfo is a module required by all modules to tell ProcessWire about them * * @return array * */ public static function getModuleInfo() { return array( // The module's title, typically a little more descriptive than the class name 'title' => 'Process Trackster Multi-Upload', // version number 'version' => 1, // summary is brief description of what this module is 'summary' => 'Creates a new page for each individual track', // Optional URL to more information about the module 'href' => '', // singular=true: indicates that only one instance of the module is allowed. // This is usually what you want for modules that attach hooks. 'singular' => true, // autoload=true: indicates the module should be started with ProcessWire. // This is necessary for any modules that attach runtime hooks, otherwise those // hooks won't get attached unless some other code calls the module on it's own. // Note that autoload modules are almost always also 'singular' (seen above). 'autoload' => true, // Optional font-awesome icon name, minus the 'fa-' part 'icon' => '', ); } /** * Initialize the module * * ProcessWire calls this when the module is loaded. For 'autoload' modules, this will be called * when ProcessWire's API is ready. As a result, this is a good place to attach hooks. * */ public function init() { // add a hook after each page is saved $this->pages->addHookAfter('save', $this, 'addNewTracks'); } /** * Adds tracks * */ protected function addNewTracks($event) { $page = $event->arguments[0]; $pages = wire('pages'); if($page->template != 'tracks') return; foreach($page->tracks_upload as $t) { $basename = str_replace(".{$t->ext}",'',$t->name); $p = new Page; $p->parent = $pages->get('/tracks/'); $p->template = 'track'; $p->title = $basename; $p->name = $p->id; $p->addStatus(Page::statusUnpublished)->save(); $p->audio->add($t->filename); $p->save(); $this->message("Added new track {$p->name} by {$p->createdUser}"); //wire('pages')->get(1014)->tracks_upload->delete($t->filename); //$deleted = $t->name; //$files->delete($t); $this->message("Deleted temporary file $$t->filename"); //$this->message("new $newname"); } $pages->get($page->id)->tracks_upload->deleteAll(); $pages->get($page->id)->save(); //$page->tracks_upload->removeAll()->save(); //$thisPage = $pages->get($page->id); //$thisPage->save(); //$page->tracks_upload->deleteAll(); //$page->save(); } } I've tried $page->tracks_upload->deleteAll(), removeAll(), $page->delete($t), $page->delete($t->name) ($page ones in the foreach loop), all kinds of things. Nothing seems to work. Pages are created fine and all, I just need these files deleted too.
-
I know how to create pages with the API. I need help with the form itself. Here's what I'm working with so far, hacked together from examples found in this forum: <?php $upload_path = $config->uploadTmpDir; $out = ''; // create a new form field (also field wrapper) $form = $modules->get("InputfieldForm"); $form->action = "./"; $form->method = "post"; $form->attr("id+name",'upload-form'); // create file field $field = $modules->get("InputfieldFile"); $field->label = "Audio File"; $field->attr('id+name','audio'); $field->description = "Upload your track(s)"; $field->destinationPath = $upload_path; $field->extensions = "mp3"; $field->maxFiles = 10; $field->maxFilesize = 2*1024*1024; // 5mb $field->required = 1; $form->append($field); // append the field // oh a submit button! $submit = $modules->get("InputfieldSubmit"); $submit->attr("value","Upload"); $submit->attr("id+name","submit"); $form->append($submit); // form was submitted so we process the form if($input->post->submit) { // user submitted the form, process it and check for errors $form->processInput($input->post); if($form->getErrors()) { // the form is processed and populated // but contains errors $out .= $form->render(); } else { // do with the form what you like, create and save it as page // or send emails. to get the values you can use // $email = $form->get("email")->value; // $name = $form->get("name")->value; // $pass = $form->get("pass")->value; // // to sanitize input // $name = $sanitizer->text($input->post->name); // $email = $sanitizer->email($form->get("email")->value); $out .= "<p>You submission was completed! Thanks for your time."; } } else { // render out form without processing $out .= $form->render(); } $content .= $out; That outputs the form but I can't drag & drop or input more than one file, and when I submit it says "Missing required value". I need to at least create one or more pages from the form submission, i.e., one per file uploaded. If possible I'd like to be able to set the title and description for each file/page as well.
-
How to write a module that adds links to edit previous or next sibling in page editor?