Leaderboard
Popular Content
Showing content with the highest reputation on 02/11/2015 in all areas
-
Hi Juergen, I'm the maintainer of the module. You could solve it by hooking after this method and return a PDF filename that depends on the language of the current user: https://github.com/wanze/Pages2Pdf/blob/master/Pages2Pdf.module#L454 I could make this method hookable for you. But I think supporting multilang would be a great feature for the module, I might need this myself soon. I'll find some time this weekend to implement it. My approach would be to create a new configuration option where you can select for what languages the PDFs are generated. When requesting a download, the PDF in the language of the current user is served. Cheers Edit: Could you post module related questions in the official module thread? Thanks. I'll try to merge them4 points
-
Taking what you have: function getGeoCodes(jsonFromCsv, callback){ // <- I added the callback parameter WITHOUT parentheses for (var i = json.length - 1; i >= 0; i--) { //AJAX requests and adding the lat / lon to the json object } // After everything is done callback(json); // <- and call it inside the function, just as you had it } // when calling getGeoCodes, you will have to pass the function as a parameter getGeoCodes(yourJson, reformatToCsv) // <- here is where we pass the function, also WITHOUT parentheses PS: I'm not sure what is jsonFromCsv in your case, but here I'm assuming it's some other parameter that you will need and it's not related to the callback function. PS2: I renamed the function inside the other function to "callback" to make it clear that you don't need to use the name of the function there, only while calling it outside. PS3: The reason that I insist so much on having the function without parentheses on the parameters is because the parentheses will cause the function to be called immediately. We want to pass it only as a reference, so we can call it only later inside the function. PS4: by the way @Jan, I didn't comment on your avatar before, but next time make sure you add a custom avatar before it's too late3 points
-
Some time ago I developed a module (FieldtypeImageExtra) which extends Fieldtype Image with the ability to add custom fields to an image. This worked well but it had a somehow restricted applicability and did not meet all of our needs. There of course are other useful image modules like CroppableImage or ImageFocusArea, but up to now there was no possibility to combine image cropping with custom fields support. So you had to decide whether to add image cropping or the possibility to add custom fields because each of those modules sets up their own field type (and input type) which cannot be combined. The new module ImageExtra allows you to have both functionalities. You can get the module from GitHub. For more informations have a look at this blog post. If you notice any problems or unexpected behaviour please let me know.2 points
-
2 points
-
Christophe, glad you are enjoying ProcessWire. There are a common set of properties available to all Inputfields, and then there are properties unique to each of them. One of the simplest ways to find those properties is to look at the @property tags at the top of the module file. Not all modules have these yet, but we're working on having them all in for PW 2.6. Here are the properties (link) common to all Inputfields, which you can see at the top of Inputfield.php. Another way to identify properties unique to an Inputfield is to make sure you've got debug mode on (in your /site/config.php file) and then go and edit any field in Setup > Fields, that happens to use the Inputfield you are interested in. Click on the "Input" tab, and you'll generally see most of the custom properties configurable from there. Hover over the little caret symbol to the far right of the field, and the API property name will reveal itself in the field label. LostKobrakai is also correct that Inputfield modules are originally intended more for admin and module use rather than front-end site use (since PW is mostly not involved in markup generation for front-end). But as more people begin to use these modules in new ways, we'll likewise try to make documentation about them more accessible.2 points
-
Hi Apeisa, Thank you so much. I have enabled the demo mode. Here are the details. Front-end Demo - bluevr.webcreate.lk Back-end Demo mode - bluevr-webcreate.lk/processwire (The username 'admin' and password 'bluevr2')2 points
-
Actually, I think SVG rocks much more than icon-fonts I can almost bet that they will fade away as soon as there is full SVG inplementation2 points
-
Hi Guys, So after reading multiple threads and searching for a solution required for a project, I decided to build a module to enable users to login to the CMS via their gmail account and hopefully the module can also be altered for LinkedIn and other Social accounts. Unfortunately the Facebook module does give you a Facebook ID and assigns the Facebook Role however I would like to assign the role, get the users email and create the user if its not in the system. I have basically taken the Facebook Login Module created by apeisa and manipulated the module to somewhat work with GMAIL. What it does now: It allows you to login but doesn't pull any data from GMAIL. Therefore it automatically logins in to the first account created in ProcessWire, but oddly changes the password, Im sure its due to the line of code in the module that is set to generate a random password via sha1. What I need it to do: If the user isn't in the system, get the gmail email, add the gmail email to the email field in ProcessWire, assign the gmail role or whatever role I want to auto assign it and log them in. My resources from Google: https://developers.google.com/accounts/docs/OAuth2 Please note, I will be updating the code as I make progress but please give input or help if you can. As always, thank you so much to everyone for their input and help, especially apeisa and craig a rodway for giving some direction initially. Here is what I have so far: <?php class GoogleLogin extends WireData implements Module, ConfigurableModule { const name = 'google-login'; //the google ID isn't used in Gmail so I am sure this will go away. const fieldName = 'google_id'; public static function getModuleInfo() { return array( "title" => "Google Login for Website", "version" => 001, "summary" => "Allows users to authenticate through their GMAIL account.", "autoload" => false ); } public function init() { } public function execute() { // Prevent association of Google Account to an existing user if ($this->user->isLoggedin()) { echo "Already logged in."; return; } $client_id = $this->googleAppId; $app_secret = $this->googleAppSecret; $redirect_uri = $this->page->httpUrl; $code = $_REQUEST["code"]; if(empty($code)) { $_SESSION['state'] = md5(uniqid(rand(), TRUE)); //CSRF protection $dialog_url = "https://accounts.google.com/o/oauth2/auth?client_id=" . $client_id . "&redirect_uri=" . $redirect_uri . "&state=" . $_SESSION['state'] . "&scope=profile email&response_type=code"; echo("<script> top.location.href='" . $dialog_url . "'</script>"); } if($_SESSION['state'] && ($_SESSION['state'] === $_REQUEST['state'])) { $token_url = "https://accounts.google.com/o/oauth2/auth/access_token?" . "client_id=" . $client_id . "&redirect_uri=" . urlencode($redirect_uri) . "&client_secret=" . $app_secret . "&code=" . $code; $response = file_get_contents($token_url); $params = null; parse_str($response, $params); $access_url = "https://accounts.google.com/o/oauth2/auth/user?access_token=" . $params['access_token']; // Add stream context $options = array('http' => array('user_agent'=> $_SERVER['HTTP_USER_AGENT'])); $context = stream_context_create($options); $ghUserData = json_decode(file_get_contents($access_url, false, $context)); $this->processLogin($ghUserData); } else { echo("The state does not match. You may be a victim of CSRF."); } } public function processLogin($ghUserData) { $id = $ghUserData->id; $u = $this->users->get("google_id=$id"); // First we create random pass to use in login $uniqid = uniqid(); $pass = sha1($uniqid . $id . $ghUserData->updated_at); // User has logged in earlier with Google id, great news let's login if ($u->id) { $u->of(false); $u->pass = $pass; $u->addRole(self::name); $u->save(); } // User has not logged in before and autogenerate is on else if (!$this->disableAutogenerate) { $name = $this->sanitizer->pageName($ghUserData->name, true); $u = $this->users->get("name=$name"); // All seems to be fine, let's create the user $u = new User; $u->name = $name; $u->google_id = $ghUserData->id; $u->pass = $pass; $u->addRole(self::name); $u->save(); } else { echo $this->renderCreateUserForm(); } $this->session->login($u->name, $pass); $p = $this->pages->get($this->redirectPage); if (!$p->id) { $p = $this->pages->get(1); } $this->session->redirect($p->httpUrl); } public function renderCreateUserForm() { } static public function getModuleConfigInputfields(Array $data) { $fields = new InputfieldWrapper(); // since this is a static function, we can't use $this->modules, so get them from the global wire() function $modules = wire('modules'); $field = $modules->get("InputfieldText"); $field->attr('name', 'googleAppId'); $field->attr('value', $data['googleAppId']); $field->label = "Google App Id"; $field->description = 'Client Id for your project. You can create one from here: https://console.developers.google.com'; $fields->add($field); $field = $modules->get("InputfieldText"); $field->attr('name', 'googleAppSecret'); $field->attr('value', $data['googleAppSecret']); $field->label = "Google App Secret"; $field->description = 'Client Secret for your project. Available in your project console here: https://console.developers.google.com'; $fields->add($field); /* $field = $modules->get("InputfieldCheckbox"); $field->attr('name', 'disableAutogenerate'); $field->attr('value', 1); $field->attr('checked', empty($data['disableAutogenerate']) ? '' : 'checked'); $field->label = "Don't set username automatically, but let the user choose username when doing the first login"; $fields->add($field); */ $field = $modules->get("InputfieldPageListSelect"); $field->attr('name', 'redirectPage'); $field->attr('value', $data['redirectPage']); $field->label = "Page where user is redirected after succesful login"; $fields->add($field); return $fields; } public function install() { $name = self::name; $fieldName = self::fieldName; $page = $this->pages->get("/$name/"); if($page->id) throw new WireException("There is already a page installed called '/$name/'"); $template = $this->templates->get($name); if($template) throw new WireException("There is already a template installed called '$name'"); $fieldgroup = $this->fieldgroups->get($name); if($fieldgroup) throw new WireException("There is already a fieldgroup installed called '$name'"); $field = $this->fields->get($fieldName); if($field) throw new WireException("There is already a field installed called '$fieldName'"); $role = $this->roles->get($name); if (!$role->id) { $this->roles->add($name); $this->message("Create role called $name"); } $fieldgroup = new Fieldgroup(); $fieldgroup->name = $name; $title = $this->fields->get('title'); if($title) $fieldgroup->add($title); $fieldgroup->save(); $template = new Template(); $template->name = $name; $template->fieldgroup = $fieldgroup; $template->allowPageNum = 1; $template->save(); $this->message("Installed template $name"); $page = new Page(); $page->template = $template; $page->parent = '/'; $page->name = $name; $page->title = "Google Login"; $page->addStatus(Page::statusHidden); $page->save(); $this->message("Installed page $page->path"); $basename = $name . ".php"; $src = $this->config->paths->SessionGoogleLogin . $basename; $dst = $this->config->paths->templates . $basename; if(@copy($src, $dst)) { $this->message("Installed template file $basename"); } else { $this->error("Templates directory is not writable so we were unable to auto-install the $basename template file."); $this->error("To complete the installation please copy $basename from $src to $dst"); } // Create hidden inputfield $input = new InputfieldText; $input->set('collapsed', Inputfield::collapsedHidden); // Create field called Google and set details and inputfield $f = new Field(); $f->type = $this->modules->get("FieldtypeText"); $f->name = $fieldName; $f->label = 'Google ID'; $f->description = 'Stores Google id for user'; $f->inputfield = $input; $f->save(); // Add the field to user fieldgroup (basically means user template in this context) $fg = $this->fieldgroups->get('user'); $fg->add($f); $fg->save(); } public function uninstall() { } }1 point
-
I did another quick module, which plugs something I always kinda missed in ProcessWire. It's just a raw overview over the access management from the templates. Nothing fancy, but useful. The visible roles and the visibility of system templats can be setup in the modules settings. I'll add this to the modules directory later. But for now it would be great to hear if anyone is missing anything or if someone does have a better idea how to name the module. 12.03.15: Renamed the module and fixed wrong information for superusers and inherited rights from the required guest role. GitHub: https://github.com/LostKobrakai/ProcessAccessOverview1 point
-
DownloadGuard for ProcessWire About DownloadGuard This simple module was developed to give clients or users a unique download link to access file downloads you offer them. Installation & Usage 1. Place the module files in /site/modules/DownloadGuard/ 2. In your admin, click Modules > Check for new modules 3. Click "install" for __DownloadGuard__ 4. In the module Settings you can edit the default count for max downloads and the time, the download should be active. 5. During the installation a Page „Downloads“ is created in your PageTree. You can create children under this Page to make Downloads. In the children page you get your unique hash and the ability to upload your file. Todo - Let the system create the download links, for easy copy and paste. BitBucket Repository: https://bitbucket.org/m_knorr/downloadguard/overview Direct Download: https://bitbucket.org/m_knorr/downloadguard/get/master.zip1 point
-
For some people it may be cool to run their own website on their own HW. But a PC is power hungry and some micros aren't powerful enough; therefore I tried to use a mini server with less than 5W power consumption. The setup: Linux (Pi: Raspbian/C1: Ubuntu) Apache2 + PHP5 MySQL + PhpMyAdmin NoIp2 (dynamic DNS client) PW (of course;-) PW is running OK on Raspberry Pi, but when you create a page with some images and resizing, you have to wait for the results between a couple of minutes and an hour; page rendering afterwards is within seconds. I wanted to try something quicker so I got an Odroid-C1 (same price as Pi - 35$) and the results are very good - C1 is about 6 times faster than Pi and after some configuring it runs stable and without problems. If someone's interested in details, don't hesitate to ask.1 point
-
Hi everybody, First of all: Thanks to everybody for keeping the community alive. Every time I search for something in the forum I find the solution. Great work! I wanted to share a small module with you / my first one. I use it in order to switch the user language on page load. Processwire GeoInfo GeoInfo is a small module that Implements Geoplugin PHP web service. Please donate to "geoplugin.com" in order to keep the service alive. The Module ads two methods to retrieve data from the web service. $page->GeoInfoIP('IP ADDRESS'); you can enter the ip address manually. If left blank the server remote address will be used. The retrieved data is then stored to the active session, in order to limit the requests. The web service gives back following data. 'geoplugin_request' 'geoplugin_status' 'geoplugin_credit' 'geoplugin_city' 'geoplugin_region' 'geoplugin_areaCode' 'geoplugin_dmaCode' 'geoplugin_countryCode' 'geoplugin_countryName' 'geoplugin_continentCode' 'geoplugin_latitude' 'geoplugin_longitude' 'geoplugin_regionCode' 'geoplugin_regionName' 'geoplugin_currencyCode' 'geoplugin_currencySymbol' 'geoplugin_currencySymbol_UTF8' 'geoplugin_currencyConverter' for e.g. $page->GeoInfoIP('IP ADDRESS')->geoplugin_countryCode; will give back the country iso code. $page->GeoInfoLatLong('LAT', 'LONG'); Enter Latitude and Longitude in order to get following information: 'geoplugin_place' 'geoplugin_countryCode' 'geoplugin_region' 'geoplugin_regionAbbreviated' 'geoplugin_latitude' 'geoplugin_longitude' 'geoplugin_distanceMiles' 'geoplugin_distanceKilometers' for e.g. $page->GeoInfoLatLong('40.712784', '-74.005941'); will give back the city name "New York City". Todo store places in json file / check if place exists implement nearby "service" https://bitbucket.org/pmichaelis/processwire-geoinfo1 point
-
After reading Include & Bootstrap on the ProcessWire website I coded a simple shell script for outputting page informations. Here is the GitHub repository with further informations and usage instructions. Long story short, you can do things like pw get "/" which outputs this: or pw find "template=basic-page,parent=/about/,sort=-id,limit=4" id template rootParent which outputs this: I don’t know if it is in any way useful, but I think it’s a fun way to output PW content and to quickly get to page informations in a rather nerdy fashion.1 point
-
Hello PW'ers, I'm a PW newbie and my first post in this forum. In the last years i was a 'hardcore' Drupal user, but i'm confused about the 'bloated' code. Make your own Drupal-theme is a hell. A few days ago I find PW. My first impression, HOW WORKS THIS??? Reading many posts in this forum, and a lot of searching on the net for good simple tutorials to understand PW. Today follow a first 'beginner' tutorial, finding in Docs of the PW-site. Wauw!! Thats an amazing CMS/CMF. I searching for a tutorial how make a select/dropdown/tag-list (similar as 'Taxonomies' in Drupal) and find it: http://wiki.processwire.com/index.php/Page_Field I try it succesfully. Ok, I have a question: I found a good tutorial in this forum how make a simple form (thanks @soma!). But how know with options a module have? Example: $field = $modules->get("InputfieldText"); $field->label = "Name"; $field->attr('id+name','name'); $field->required = 1; $form->append($field); In the above code, i see a label, attr, required But how can I know with options are available for a module? PS: Sorry for my bad english Regards, Christophe1 point
-
1 point
-
1 point
-
Think I've finally gotten to the bottom of this. MAMP Pro was using 80 , 443 and 3306 as ports for Apache, SSL and MySQL. Setting it back to the defaults of 8888,8890 and 8889 increased speed and page refreshes from 9+ seconds to 2-3 seconds. I also wonder if the port 80 was clashing with Skype. Just glad to have a platform I can now work on locally.1 point
-
I had a problem with this error "Call to a member function isLoggedin() on a non-object" when using the login-code from Ryans very first post in this thread here. Just like adrianmak here: https://processwire.com/talk/topic/8835-cause-internal-server-error-when-login-with-a-wrong-username-or-password/ The code at the very beginning of this thread goes like this: $user = $sanitizer->username($input->post->user); But that is bad because $user gets overwritten !? Jan Romero gave the answer in that other thread ... Now I use this and everything is fine: $username = $sanitizer->username($input->post->user); $pass = $input->post->pass; if($session->login($username, $pass)) { $session->redirect($root_url."login/"); } Could be related to some other bugs on this forum? When you search for "Call to a member function isLoggedin()" you get some topics displayed - maybe the examples at the beginning should be corrected!?1 point
-
Fun fact about SVGs: Internet Explorer will not scale <img> SVGs properly if they don’t have the viewBox attribute. I’m not sure if it was Inkscape or the optimizer I used, but my SVGs were missing this, and I had to edit it in for IE: width="1024" height="512" viewBox="0 0 1024 512" Without viewBox, the image would remain 1024x512 in IE, but it won’t scale it down and clip it to the <img> tag’s dimensions instead.1 point
-
Feel like you left out the most interesting parts there It sounds like you’re not using jQuery, but if you did, Ajax requests would return Deferred objects that expose done events. You could then use $.when to bind these Deferreds together into a single Deferred that fires such an event once for the entire queue, once all “inner” Deferreds have finished. I recently had to wrap my head around this. Voodoo is an apt description. I think in vanilla JS (I hope this is not the name of some JS library ) you would create an XMLHttpRequest object for each request, whose onreadystatechange events you handle in one function. There you could naively count the successes in a global variable and do your thing once you have all of them. So it kinda depends on what the requests look like and what events you can subscribe to. The requests should run in parallel if you simply send() them one after the other, i. e. the program will not wait for the server response until it executes the next request.1 point
-
There's also Jumplinks, which supports redirects containing index.php, without needing to rename it.1 point
-
Other will answer this with more authority than I Ollie, but I have found PW beta to be more stable and robust than some other production s/w. So on occasions I have used beta for production sites, after extensive tests (so far all of which always work flawlessly). It really is a very, very good CMS. Enjoy1 point
-
Today updated one site from stable to latest dev 2.5.18 no trouble whatsoever, all works great. Anybody any idea when it is ok run this on production sites? Thanks for such a wonderful CMS!1 point
-
Cool.... Wondering though, what if a page has 1000s of descendants? That find could choke up....1 point
-
Thank you both, Soma and LostKobrakai. Textformatter and getUnformatted in combination were what I was missing! Here's the working code - short and to the point: public function formatValue(Page $page, Field $field, &$value) { if( $page->isMultiLang == 1 ) { if( $this->user->language != 'default' ) { $value = $page->getUnformatted($field->name)->getDefaultValue(); } $value = preg_replace_callback('/\{TR:([^}]+)\}/', array($this, "translate"), $value); } }1 point
-
They're already usable, they just wheren't intentionally developed for that. Only documentation is lacking, while Soma's topic and the comments in the mentioned core files do already cover most of the information, just not in a very easy-to-enter way. And there's still FormBuilder, which does provides a grafical ui for setting up fields (and lots more).1 point
-
The main reason for icon-fonts is that they are much easier to use than svg. On the other hand, the moment one understands the flexibility and power of svg, svg becomes the primary choice. In most projects I use a combination of both. If the customer is happy with the default style that fontawesome or icomoon provides (and most customers are), I use fonts, because I'm lazy. If the customer wants something more unique, I rely on svg. I don't know if it's a german phenomenon but many customers also demand that the site is working with IE8 and then icon fonts become an alternative. In most cases icon-fonts are much bigger, you have to provide four (or five) different font-types, which is grotesque when you compare it to a set of svg icons.1 point
-
There's a number of posts here in the forums about restricting users to only be able to edit the pages they created... Here's some modules that you could look at/customise to help you get started http://modules.processwire.com/modules/custom-page-roles/ http://modules.processwire.com/modules/page-edit-per-user/1 point
-
That's why these files are kept. You could always exclude those hidden ones from uploading or git, but having at least the last version available can be useful. The think the only way to get to those older dev versions by yourself would be cloning the repo and moving the HEAD (git) to the last commit before the version bump.1 point
-
Use the CoreUpgrade module. It doesn't remove anything, but just hides the old wire folder / index.php and .htaccess. To roll back just rename/delete the current ones and change the hidden ones back, like so: .wire-2.5.17/ to wire/. In github there's no way to have these versions displayed as ryan does not "mark" them as releases which they really aren't. The version number just comes from some core file, where it's hardcoded.1 point
-
Use google webmaster tools, option view as googlebot and if it can display email address, then EMO failed.1 point
-
1 point
-
1 point
-
This API was never intended to be used by developers other than for modules, that's why there is little documentation besides the thread you've mentioned. The best solution would be taking a look at the files itself: wire/core/Inputfield.php & all those wire/modules/Inputfields/*.module. Most of them do have a fair amount of comments, so you should get along after some time. P.S. It would be nice to ask such questions in the thread it belongs to.1 point
-
It is pretty new (I think maybe a year now?) - that is something Ryan came up when need to hook into often used methods came for the first time.1 point
-
Hello Peterpp, maybe it's a problem with the Apache Version you use. Because I have set up a blank PW2.5.3 with DG on my Apache 2.2 with PHP 5.6, and everything is running fine. I'll try to find a spot, where I can test with a 2.4 Apache. Or maybe, someone's here to help. I'm trying to fix this behaviour as soon as I get my hands on a new Apache! Kind regards, Martin1 point
-
I really like svg not only because they are scaleable but they allow me to interact relative easily with them. For example I'm currently working at the mess of my CV (which we call in Germany "Zickzack-Lebenslauf") and so I aim to built some scattered items connect them with lines and when you hover you get the relevant data. SVG really rocks (nearly as much as Icon-Fonts) and I hope someday it will become common sense to use them.1 point
-
The api way would be not using array notation but one of these. $page->repeater->first(); $page->repeater->eq($i); $page->repeater->last();1 point
-
Seems like my wish came true...even without formally requesting it I agree this is the way to go. Good job!1 point
-
1 point
-
Ryan, Whatever train you are on -- don't get off. All this new stuff is great! I should just go to bed now (7:00pm here) so I can wake up at 3:00am and check all this stuff out while my kids are still asleep. Of course, that can be risky, one "this rules!" that's a little too loud and I have a one year old up several hours early. That's no picnic.1 point
-
I've been working part-time, for several months, on an administration and attendance tracking system for a local trampoline and gymnastics club where I also do a little coaching. Been trying to build this up incrementally in the form of re-usable modules and I have already released some of these (FieldtypeTime, markup crossfade & google calendar embed) but a couple of new fieldtypes and the major module - which handles club sessions, members, scheduling and attendance tracking - are still being tweaked. The system runs on the club intranet with the club administration being done via PW's admin interface and the homepage being displayed on the check-in kiosk at the front desk (a touch-enabled monitor in portrait orientation.) The athletes use the kiosk to check-in as they arrive and club information, signage and advertising can all be shown in the background on the kiosk thanks to the markup-crossfade module. Club staff can quickly and easily create new slides in the kiosk display sequence or modify what's already there (slides for fees-due, car blockages, session times etc) as well as seeing who is in attendance and for what. I don't yet have permission to post full screenshots of the athletes in public places (remember this is all internal to the club) but once I get permission I'll do a write-up of the site. In the meantime here's a few teasers. Firstly, on the check-in kiosk... ...and some from the back-end...1 point
-
I have a hard time understanding what people mean by "MVC" sometimes, but it seems to me that the PW module system is natural for building this way. You can set the module to autoload and then use it as your Controller. Keeping all your logic in there, the template then becomes your View, and the Pages API already handles the Model side of things. But I could be totally wrong...1 point
-
In a way it's sad that companies praise the way of reinventing the wheel. But that's business.1 point
-
Ah. You’re overriding ProcessWire’s $user variable here: $user = $sanitizer->username($input->post->user); Now $user is just some string the visitor entered, and no longer the special user object. Just use a different variable like $username or something. The same thing applies for other API variables like $page, $pages, $session, etc. as well, of course.1 point
-
So I spent some time fiddling around with this tonight and managed to get modal editing of page field pages working with the addition of just a few lines of code in InputfieldPage.module: InputfieldPage.module The modified file is attached. I commented the lines that I added with /* MJS 1/15/15 */ You'll want to put this file into /site/modules/ so you don't overwrite the core. Once it's up there, you should see an option in the field config settings for your page field that says 'Allow pages to be edited from field?' Check the box. This only works if you're using ASMSelect with your page field. The catch is that you have to save the page before the modal edit links become available (like when editing fields in the template editor). I think the only way around this would be to significantly re-engineer the ASMSelect inputfield with some AJAXy stuff. Not my strong suit. EDIT: There is a module for this now with more features. Use it instead! https://processwire.com/talk/topic/9857-module-page-field-edit-links/1 point
-
1 point
-
upgrade.php is not a ProcessWire file. I'm guessing maybe it was a leftover from a previous WP or Joomla install? It sounds like it could be related to the exploit you experienced, but be careful not to assume it ends there. ProcessWire's core does not have very many input opportunities on the front-end of your site. Actually, the URL itself is really the only input ProcessWire deals with on the front-end, and that is validated by the htaccess before being sent to PW, and then thoroughly sanitized then validated again by the core. As a result, it's unlikely for ProcessWire itself to be exploited in the same ways that some other CMSs might be, simply because there are a lack of input opportunities to a guest visitor. What ProcessWire does instead is give you an API that lets you control all the aspects of when user input results in something output. If there were to be an exploit on a particular PW site, it would be much more likely to be the result of the code unique to that site, or a 3rd party module, rather than PW itself. If you were dealing with a site that had other software running, either presently or in the past (perhaps WP powering a blog alongside) then it'd be much more likely for that to be the source of the issue than PW. In fairness to WP, most exploits have to do with 3rd party WP plugins or themes and not WP itself. WP and Joomla are also much larger targets than PW, so they are usually broken into with automated scripts rather than actual people sitting at their computer. When you've got a site that you know has been broken into at the filesystem level (like yours might have been), it's unusual for it to be limited to just one file. There are usually backdoors built elsewhere. Even if the site is fixed for the moment, it's good to still think of everything as tainted until proven otherwise. I'm not necessarily a fan of restoring from a backup in this case, unless you know for certain that the backup itself does not contain the exploit. Sometimes a backdoor will be present for months before taken advantage of. If you had Joomla running on this server a long time ago, the exploit may have originated there and simply been hidden somewhere on the file system. The first thing you'd want to do is remove any other software installed on the server that doesn't need to be there–old copies of WP, Joomla, etc., or files leftover by them. If you aren't certain, then just move it to a non web accessible quarantine directory. For your ProcessWire site, you don't need anything in your web root directory except for: /wire/, /site/, /index.php and .htaccess. Remove your entire /wire/ directory and put in a new fresh copy, as well as your /index.php and /.htaccess file. Basically do the same thing you would do if performing an upgrade. In /site/modules/ you may have some 3rd party modules installed. Replace each of the directories in /site/modules/ with fresh copies. This is the same thing you'd do if upgrading those modules. That essentially leaves /site/ and everything in it to analyze. If the hack originated from an automated script targeting DrumlaPress, chances are it left your PW installation alone, but you never know–it might have gone after every single PHP and JS file it could find on the file system. You'll want to look for anything unusual in your /site/templates/*.php files and /site/config.php file. By unusual, I mean anything that you didn't put there. Start by looking at the beginning and ending of each file. Red flags are usually extra <script> statements, base64 function calls, exec function calls, extra JS attributes on markup elements that you didn't put there (like onclick), include or require statements with variable names in them or referencing files you don't recognize. Also consider that new directories may have been introduced anywhere. I would download a copy of your entire /site/ structure and analyze it locally, looking for any extra files or directories that you didn't put there. Also be on the lookout for extra .htaccess files, and give them a close look if you find any. Meaning, you'll need to make sure you are seeing hidden files (those preceded with a period). Compare your /site/ structure to a /site-default/ structure as included with a new copy of PW. Once you've cleaned your /site/ directory or at least verified that it's clean, make a good backup of your site so that you've got a known clean starting point (hopefully). Open a browser to your site with Chrome and go to View > Developer > Developer Tools. Click to the "Network" tab. Reload the page. Look for any offsite requests that you don't recognize. That may reveal something hidden that might still need to be cleaned, but hopefully not. Now click to the "Elements" tab. This shows the post-JS markup of your site. Look for any generated elements that you don't recognize, especially at the end or beginning. This again can reveal extras that have been added into your page by an exploit. Lastly (or maybe firstly?), take a look at your file permissions. If on a shared host, you want to be certain that your files aren't readable or writable to other users on the same server. Especially your /site/config.php file, and your /site/assets/ directory (and everything below). What permissions are ideal here depend on the web host and what type of PHP they are running, so it's best to inquire with them on how you can have files writable to your website that aren't writable by other accounts. Btw, I have never seen or heard of a compromised PW installation, regardless of what other compromised software was running on the server. I have seen plenty of compromised WP installations that had PW running alongside them. Thankfully, the PW installation has always been left alone, with the exploit limited to the WP installation. But it's best to go into these things assuming everything on the server is tainted, so always play it safe.1 point
-
Something like this should work... $t = $templates->get('basic-page');//get the template $f = $t->fieldgroup->getField('summary', true);//get the field in context of this template $f->description = "This should be the description";//value of the field $fields->saveFieldgroupContext($f, $t->fieldgroup);//save new setting in context Edited for clarity... In this example, we are changing the description of the field 'summary' in the context of the template 'basic-page'.1 point
-
Hi there, the email confirmation always land to the spam folder, and the sender address is ftp051214@www05.servertown.ch (which is the name of the server i'm using). Where can i edit the sender Email address, and will it solve the spam issue? Thanks1 point