-
Posts
1,331 -
Joined
-
Last visited
-
Days Won
61
Everything posted by BitPoet
-
Is mod_security enabled in the web server? If yes, it would be the first suspect.
-
FieldtypeTextareaLanguage - set 'Text Formatters' and 'Inputfield Type'
BitPoet replied to didhavn's topic in API & Templates
The textformatters attribute is defined/set in FieldtypeText::___getConfigInputfields and its value is used in FieldtypeText::___formatValue. -
Is your harddrive full? It might be that the files in question don't fit on the drive where PW resides while the images get downsized and can manage to squeeze into the leftover space.
-
-
In most cases you can solve that through field permissions. Add a custom role if you need some non-superusers to change those layout images, then check "Manage Access" for the field, add your new role and remove the regular editor role. Only editable fields will be selectable as upload targets. You should be able to preselect one image field with a piece of custom javascript (you can use AdminCustomFiles to inject your script into the correct process), but I don't have an example for that. If you need to make things more dynamic, you probably have to do some text search and replace in the output of ProcessPageEditImagSelect::execute since the method that gets the list of target fields for the "Upload Image" button isn't hookable.
-
Actually, you wouldn't even have to pass the filename. If you assemble the image URL like this, you could just as well use a unique parameter that tells your hook to output the image contained in whatever field you want and can stop worrying about exposing the wrong file. Like {$page->url}?showprofileimage=1.
-
That's likely not going to be trivial. Adding check_access=0 in a selector to display the link is quite another thing as serving the secure file to a guest user. When you have pageFileSecure enabled, the following happens: PW prefixes the file directory site/assets/files/[PAGEID] with $config->pagefileSecurePathPrefix ("-" by default so it will be site/assets/files/-[PAGEID]) When the browsers tries to show the image (i.e. open the URL /path/to/pw/site/assets/files/1258/image.jpg in a separate request), the file isn't found by .htaccess .htaccess hands off the request to index.php index.php calls PageRender::execute with the request URL PageRender::execute checks if the request is to a file, then checks if the page it belongs to is published and viewable by the current user Since $user->hasPermission('page-view', $page) returns false (the guest user doesn't have view permissions) that fails (otherwise, PW would prefix the path now and output the file) PW outputs the 404 page Since the method where the check is are done is not hookable (and some necessary properties and methods are protected, i.e. not reachable from a hook) you'd probably have to hook before ProcessPageView::execute and duplicate a lot of code from ProcessPageView or hook after User::hasPagePermission and at least duplicate ProcessPageView::checkRequestFile in both cases, match the file URL to $page->image to prevent handing out a access to other file/image fields on the page Another approach (if the images aren't too big and the protected pages aren't too many) would be to include the real image data as data URIs: <?php foreach($protected_pages as $protected_page) { echo $protected_page->title . "<br>"; $fn = $protected_page->image->filename; $imgdata = "data:" . mime_content_type($fn) . ";base64," . base64_encode(file_get_contents($fn)); echo "<img src='$imgdata' alt='{$protected_page->image->description}' />"; } If the images are small enough but you have many pages, using PW's pagination might be an option too.
-
IMHO building your prototype with PW gives you a solid base from which you can go in every direction. You can build just a part in Vue and let the Vue app grow over time. There's a little bit of effort involved to tie PW's pages, fields and templates and Vue templates together smoothly without a lot of overhead, but an experienced Vue dev should be able to wire that up quickly and in a reusable way (Vue would be my choice there as well). Exposing PW pages and limited write actions through ajax isn't hard to do either. It's also a walk in the park to migrate PW content into less normalized "external" tables with a small bootstrap script if performance really requires it, so unlike other CMSes where you have all kinds of different things (posts, pages, parts, whatever) in different structures, you don't really lock yourself in with PW. I agree with @LostKobrakai insofar as that there are in fact a few areas where a custom tool will get you further, like if you need a full-blown discussion forum. The choices there are rather limited if you want a good integration. Invision (the software this forum runs on) seems to be rather straight forward in that regard. I have tried my hand on a phpBB3 integration module and while the basics mostly work, it's really a PITA in some parts (like outdated examples and misleading documentation) and I've run out of time to get it into a really usable shape. There are probably a few Laravel forum components I've never heard of that can get you most of the way as a half way option. I think that will be the hardest part to decide, where will PW (or any other CMS or own development, in fact) ever only be the second best choice compared to a single purpose tool you can integrate.
-
Here's a try: <?php echo (selectorsMatch("baths>1, template=listing", "template=listing, baths>1")) ? "Match" : "No match"; function selectorsMatch($sel1, $sel2) { $s1 = new Selectors($sel1); $s1->sort('field'); $s2 = new Selectors($sel2); $s2->sort('field'); return "$s1" == "$s2"; } Not sure how this behaves with OR-groups, but it should be fine for simple AND selectors.
- 1 reply
-
- 2
-
-
In my personal opinion the definition is rather fluid and depends on too many factors to give a generic rule, but I consider a site highly dynamic when multiple components of often visited templates (especially home and other landing pages) have user or group specific content and that content changes more often than on a daily basis. Whenever I see "social" or "communities" in a site's description, that's likely the case.
-
Find queries are cached for the lifetime of a request. Caching them more permanently needs additional code. I think there was an example for using MarkupCache to store JSONified query results in the forum a while ago, but I might remember wrongly. With highly dynamic sites, everything you know about caching best practices is at first no longer valid. Until you start factoring out the dynamic parts, that is. Decouple searches from the database by using a dedicated in-memory search engine (Lucene, OpenSearchServer etc.) to avoid high loads and table level locks. Cache IDs and values retrieved from frequent searches in memory (like newest n posts/comments), and when you scale up, delegate the job of updating those to cronjobs to eliminate any delays caused by rebuilding expired memory caches. Retrieve dynamic parts of the page through JS in JSON format and render them with a frontend framework so the static parts and templates can be served from the filesystem (that's where ProCache ties in). Design your pages to use placeholders for dynamic content so your users don't have to wait for client side rendering of dynamic content before they can start using the page.
-
If you use mod_security with a CMS it isn't specifically aimed at, this is exactly the kind of nonsensical errors you will get since its pattern matches will only make sense in the context of that CMS (mostly WP). Even with a supported CMS you will likely encounter that kind of error if you build a complex, dynamic site or use less popular plugins, and you will have to adapt the rule sets. I'm pretty sure you'll find log entries from mod_security that match your 403s and 404s.
-
@Xonox, have you seen Inputfield Page Autocomplete?
-
PHP probably runs under the user configured in your anonymous authentication settings. In IIS manager, click on your website, then on "Authentication". Select "Anonymous Authentication" and click "Edit" in actions bar at the right. There you will see the user (default: IUSR). Grant this user modify permissions on the assets folder.
-
Contacting them about the problem is never a bad idea. Even if it's something you can change yourself, they'll likely be able to give you pointers where to look.
-
This error is caused by PHP being unable to reach a source of randomness to generate random numbers (like, in this case, session IDs). The exact cause can vary, ranging from missing read access to /dev/urandom (check if it is included in php.ini's open_basedir if that restriction is configured) over too old PHP versions to improperly set up chroot jails (e.g. missing to include /dev/urandom) and probably some scenarios I can't think of off the top of my head.
-
[SOLVED] Problem while getting a custom Fieldtype to work
BitPoet replied to monollonom's topic in Module/Plugin Development
What happens if you extend FieldtypeMulti instead of Fieldtype in FildtypeMapRoom? -
Site Profile Exporter creates incomplete config.php
BitPoet replied to wbmnfktr's topic in General Support
Site Profile Exporter doesn't account for function code in config.php, as it has very limited line parsing capabilities. Basically, it concatenates lines until it encounters a ";" at the end of the line. I don't think there's a quick fix to the exporter, but perhaps setting $config->sessionAllow in the init method of an autoload module might work. -
Yes, you can use the code from InputfieldText::getConfigInputfields almost verbatim in a site/ready.php hook, but since that configuration property isn't initialized in InputfieldDatetime and not set in the field's attributes, you have to add that logic too in another hook. A possible place to do that is in Field::getInputfield: <?php namespace ProcessWire; // Add the configuration field: $wire->addHookAfter("InputfieldDatetime::getConfigInputfields", function(HookEvent $event) { $inputfields = $event->return; $required = $inputfields->getChildByName('required'); if($required) { $required->set('columnWidth', 50); /** @var InputfieldCheckbox $field */ $field = wire('modules')->get('InputfieldCheckbox'); $field->attr('name', 'requiredAttr'); $field->label = $event->object->_('Also use HTML5 “required” attribute?'); $field->showIf = "required=1, showIf='', requiredIf=''"; $field->description = $event->object->_('Use only on fields *always* visible to the user.'); $field->icon = 'html5'; $field->columnWidth = 50; if($event->object->requiredAttr) $field->attr('checked', 'checked'); $required->getParent()->insertAfter($field, $required); } }); // This populates the requiredAttr property and sets the HTML attribute // on the InputfieldDatetime instance: $wire->addHookAfter("Field::getInputfield", function(HookEvent $event) { $input = $event->return; if(! $input instanceof InputfieldDatetime) return; $field = $event->object; // Configuration value retrieved from the field's settings in the database: $requiredAttr = $field->requiredAttr; // Probably not necessary but there for consistiency: if($requiredAttr) $input->requiredAttr = $requiredAttr; // This sets the HTML attribute if($input->required && $requiredAttr && !$input->getSetting('showIf') && !$input->getSetting('requiredIf')) { $input->setAttribute('required', 'required'); } });
-
Comments: email notifications to varios admin
BitPoet replied to franciccio-ITALIANO's topic in Getting Started
Three solutions immediately spring to mind: a) Create different comments fields for each group of pages (downsides: you have to keep other settings in sync and page queries may have to run over both fields) b) If all comments pages are at the same depth (or not too deeply nested) and each has a unique (might also be grand-) parent, you can create a field on those ancestors that holds the admin contact email and use the "field:" syntax in Admin notification email: field:parent.adminemail // or, for grandchildren field:parent.parent.adminemail You could even set multiple sources this way if the adminemail might be either on the parent or the grandparent (just make sure it isn't set on both). The comments field will only use valid emails, so if a parent or grandparent doesn't have the field (or doesn't exist), that entry will be ignored. field:parent.adminemail,field:parent.parent.adminemail c) In some scenarios, you want to send notifications to the user that created the page. In that case, you can use field:createdUser.email The big downside of that approach is that when the creator of the page is no longer available to approve comments, the createdUser field has to be changed or a different email address assigned in their profile settings (and comment notifications might get lost if nobody thinks of that). It should also be possible to populate $field->notificationEmail through a hook, but from the top of my head, I can't name a convenient method to hook into. -
In the database, datetime fields have a time part that is set to the current time when saving a new value for a date only field. "today" is interpolated by PHP's strtotime function to 00:00:00 of today's date, so <= will only match articles posted exactly at midnight. You probably want to use $news_posts = $page->children("limit=10, news_date<tomorrow"); instead.
-
Blog's Notification in a page, as wordpress widget!
BitPoet replied to franciccio-ITALIANO's topic in Getting Started
You can take a look at one of my blog site profiles, e.g. Editorial, to see a working example you can adapt to your site. It's built on PW and the blog module @pwired linked. The "widgets" are pages with a PW template (that doesn't prepend and append anything in the template's family settings) and PHP file generating the output for each widget a page living under /widgets To display widgets on a page, the blog-settings template for the page where the site's configuration is stored has a page reference field "blog_widgets" where one can assign and order the widgets to be shown. In site/templates/blog_sidebar.php the settings page is retrieved and a small code snippet like this renders all selected widgets: foreach($blogSettings->blog_widgets as $widget) { echo $widget->render(); }- 3 replies
-
- 2
-
-
- blog
- notification
-
(and 1 more)
Tagged with:
-
getting page title after images shuffle from multiple pages
BitPoet replied to lickny2001's topic in Getting Started
A Pageimage instance knows the page it belongs to. See the bottom of the Pagefile documentation (section "Other") for reference. foreach($random_thumbs as $r) { echo "<img src='{$r->url}'> <p>{$r->page->title}</p>"; } -
It's very, very bad practice to use sleep() in a server side script, that is why documentation on working around the pecularities of PHP's buffering (and thread execution) is so sparse. sleep() blocks the whole thread it is called in, and under heavier load, it makes servers utterly unresponsive. There also fine differences in buffering behaviour depending on how PHP is executed (mod_php, FastCGI, classic CGI...) The usual solution to situations where you are tempted to call sleep() is to poll until the condition you need to wait for has been reached, either using classic reloads for the current page or with AJAX. Nowadays, websockets are also used to split off parts of the work to different processes and notify the "owning" session of changes of state in the backend.
-
Integrity constraint violation: 1062 Duplicate entry
BitPoet replied to ZionBludd's topic in General Support
Simply don't set a name, then PW will take the title you assigned and create a unique name from it by running it through $sanitizer->pageName and appending an incremental suffix if the name has already been taken. There can only be one page with a given name under the same parent. You can read some more about it in this discussion: