Jump to content

Autofahrn

Members
  • Posts

    328
  • Joined

  • Last visited

  • Days Won

    10

Everything posted by Autofahrn

  1. Out of curiosity I've just dived a little deeper and agree that the limiting factor is the database field. The interesting point is, that my limitation differs, as I get 6 significant digits. So storing 15248.25 returns 15248.2, which is a little surprise, since a regular float should provide 7 significant decimal digits (https://en.wikipedia.org/wiki/IEEE_754). Anyway, if two decimals are relevant and values larger than 10000 need to be handled, float is not your friend. Btw: "float" in PHP is double precision, able to provide 14 significant digits.
  2. Just verified that this can be made running in combination with @BitPoet's simple language switcher: I've basically added a text field url_domain to the language template and moved the default language detection from _init.php into the updatePath method (so my loop makes much more sense now): public function updatePath($path) { $httpHost = $this->wire('config')->httpHost; $languages = $this->wire('languages'); // Setup default language by domain root foreach($languages as $lang) { if(($lang->url_domain != "") && (strpos($httpHost, $lang->url_domain) > 0)) { $this->user->language = $lang; break; } } This change eliminates most of the other default processing, since the default already set based on the domain name. Throughout the site I'm using localUrl to generate internal link urls, that code was changed to get rid of the language segment in case it is the default for the current domain: public function hookPageLocalUrl(HookEvent $event) { $lang = $this->getLanguage($event->arguments(0)); $config = $this->wire('config'); if(($lang->url_domain != "") && (strpos($config->httpHost, $lang->url_domain) > 0)) // Default for this domain? $event->return = $config->urls->root . ltrim($event->object->path, "/"); else $event->return = $config->urls->root . ltrim($lang->name . $event->object->path, "/"); } The benefit of this is, that languages can be added to the site without the need having an associated domain for each. And it does not break old links on my site, which still have the language in the url. So www.domain.com/pagename and www.domain.de/en/pagename still retrieve the same content and another language may be reached through www.domain.de/fr/pagename or www.domain.com/fr/pagename for example. Edit: Just in case someone wants to see this in action: www.versus-x.com (english) www.versus-x.de (german) www.versus-x.com/de/ (also german) www.versus-x.com/fr/ (french, incomplete, for testing only) www.versus-x.de/fr/ (french, only parts as well)
  3. Clever idea. I've just test-implemented that on one of my multi-language sites with .de and .com domains and it works pretty smooth following these steps: all DNS entries point to the same PW instance root in site/config.php I've added all allowed domain names in _init.php I've quickly added this (only for com, should match a field in language setting): if(strpos($config->httpHost, ".com") > 0) { foreach($languages as $lang) { if($lang->name == 'en') { $user->language = $lang; break; } } } That's it, now all language fields follow the selected language. Switching between languages is now switching between domain names. Thanks for that hint!
  4. you are looking for something like: output.style.color = "red"; https://www.w3schools.com/jsref/prop_html_style.asp
  5. For me there are two issues, the SQL errors and the strange class not found errors (which sounds more like a corrupted filesystem). On what kind of system is this installation running? If the files get corrupt, I'd more expect some syntax error not a class not found. Could this be some module load order issue? Missing module dependency or similar? Anyway, this should not break the SQL side.
  6. Looks similar to this one: Do you have some caching enabled? Sounds like the cached files went corrupt for some reason and rebuilding the cache after touching the sources fixes it. Very strange.
  7. In which situation do you not have the required checkbox on a datetime field? On all field types I'm aware of the Required checkbox is located on Input tab. Or do I miss something?
  8. Can you give me more code context? I've just added that to my previous test code and it works quite well: <?php namespace ProcessWire; $test = $page->protabla->makeBlankItem(); // getNew(); $test->name = date('D, d M Y H:i:s'); $test->notes = 'my note'; $test->entrega = time(); // date("Y-m-d H:i"); // $test->save(); $page->of(false); // required for page save $page->protabla->add($test); $page->save('protabla'); // only save that field $page->of(true); $content = "<h4>{$page->title}</h4>"; $content .= "<table>"; foreach($page->protabla as $pt) { $content .= "<tr><td>{$pt->name}</td><td>{$pt->notes}</td><td>{$pt->entrega}</td></tr>"; } $content .= "</table>";
  9. When I set DateTime fields from API I just use the unix timestamp like: $newRow->entrega = time(); Well, doesn't help if your time source is a string.
  10. If that field should only transport some additional data, why not simply add some markup? $form->appendMarkup = "<input type='hidden' name='some-name' value='some-value' />";
  11. Well, either you strip those headers manually (which you did) or enumerate over all containers, search for the user table and continue to process that one (code only to get an idea, probably contains some typos): $AllData = json_decode($http->get('localhost:8888/playwood/pw_users.json'), true); foreach($AllData as $container) { if(($container['type'] == 'table') && ($container['name'] == 'name_users')) { $UserData = $container['data']; foreach($UserData as $v) { : } break; } } If the generated users are named from current timestamp then I suppose that $UserPwName is not set correctly. Did you check that $UserLoginName is read correctly from your data (maybe adding d($UserLoginName); and d($UserPwName); helps).
  12. We are here to exchange ideas, so please try to stay besserwisserisch as I understand that I needed to explain my approach a little better ?. My JSON data not only contained user login information but other stuff like avatar images, signatures various settings (from the origin) etc. My template is more a viewer for that data which allows to import or update contents on a per-user base. Of course I could also create that as a module, but for that one-time use going with a template was more straight forward for me. I prefer making a module for the reusable stuff.., That's what I meant that migrating the password (probably) does not work, unless you are able to decrypt the hash code stored in the database. I'd set some randomized password and integrate the LoginRegister module along with ForgetPassword so users are able to restore their accounts on their own. And, yes, I've omitted the closing brace in my snippets (thought it was too obvious). The row looks ok, but maybe your JSON includes some additional headers which need to be referenced first (the part before the first row of user data) like this: { "Type" : "UserData", "Users" : [ { "ID": .... Then your foreach would have to start on $UserData["Users"] and you could verify $UserData["Type"] before starting the import.
  13. Sure, using the debugger for such one-shot solutions may be faster to go. In my case the template contains much more functionality, since it generates a regular visible page. There I could pick the users to import or update information after changing fields in the user template etc.
  14. If you can export the user as JSON, it should be simple enough to write a small importer in PHP. When I did similar, I created a template with a simple file field holding the JSON containing the user database. The associated template php starts like this: <?php namespace ProcessWire; if(isset($page->json_file)) $UserData = json_decode(file_get_contents($page->json_file->path . $page->json_file->first()->name), true); else $UserData = [ ]; // ensure always set, yet empty. depending on your JSON structure you'll iterate through your users somewhat like this: foreach($UserData as $v) { // Fetch whatever fields should be imported $UserLoginName = $v["LoginName"]; $UserRealName = $v["RealName"]; $UserMail = $v["EMail"]; In my implementation I'm building a pagename from the original name and check if the user actually exists: $UserPwName = $sanitizer->pageName($UserLoginName, true); $usr = $users->get("name={$UserPwName}"); Of course you only want to add a user which does not exist yet (you may do other things like update for existing users): if($usr->id == 0) // User does not exist { $usr = $users->add($UserPwName); // Create user if($usr->id) // Success? { $usr->of(false); // Prepare for update $usr->email = $UserMail; $usr->addRole('imported-user'); // add some special role here // add more fields depending on your use case // $usr->user_name = $UserRealName; $usr->save(); } else { // may $log->error("ERROR creating user {$UserRealName}"); } } Shouldn't be too difficult to adapt for other scenarios. Take care of the passwords, which likely can't be migrated that way!
  15. Try this: $test = $page->protabla->makeBlankItem(); // getNew(); is wrong, allocation done by makeBlankItem() $page->of(false); // always a good idea $test->name = date('D, d M Y H:i:s'); $test->notes = 'my note'; // $test->save(); // not required $page->protabla->add($test); $page->save('protabla'); // only save that field $page->of(true); functional test code (with delayed output) here: <?php namespace ProcessWire; $test = $page->protabla->makeBlankItem(); $page->of(false); // always a good idea $test->name = date('D, d M Y H:i:s'); $test->notes = 'my note'; $page->protabla->add($test); $page->save('protabla'); // only save that field $page->of(true); $content = "<h4>{$page->title}</h4>"; $content .= "<table>"; foreach($page->protabla as $pt) { $content .= "<tr><td>{$pt->name}</td><td>{$pt->notes}</td></tr>"; } $content .= "</table>"; Edit: Maybe this should be moved to the ProFields Table support forum.
  16. and line 180 is which one? I'll setup a test and come back...
  17. did you save the page afterwards? $test = $page->protabla->getNew(); $page->of(false); // always a good idea $test->name = 'my name'; $test->notes = 'my note'; $test->save(); $page->save('protabla'); // only save that field $page->of(true); (only guessing)
  18. I'm used to retrieve the current language from $user->language. I'd personally prefer to write such conditional code like this, but that probably doesn't make a difference: <?php if($user-language == 'fa') echo "<link rel='stylesheet' href='{$config->urls->templates}css/main-fa.css?v=2.5' type='text/css'>"; ?> Did you verify that your $language is actually set to "fa"?
  19. $p->of(false); // should go first $p->resp = "33"; // expected to work $p->save();
  20. At least I don't say no regarding that idea. ? But moving that framework in to a module should be the goal in any case. Currently its more a grown bunch of functions which urgently needs some maintenance to split my ~1500 lines of code in _func.php into something self documented. This has to happen in a near timeframe anyway and creating a module from the core functionality doesn't seem to be too much work on top. To make this public, I probably first need to get rid of the (great!) Form Builder module, which is kind of overkill anyway but simplified playing around with CKEditor configurations and field layout a lot. Will check next months, can't promise anything yet.
  21. If thats not global enough, why not send an additional CSS file to the client whenever rtl is required, which globally adds direction:rtl; to all necessary tags?
  22. Indeed, but implementing that as a module was dropped rather quickly, since I simply didn't had the time to make it multi purpose and focused on the necessary stuff. Did I mention that this project actually started mid April?
  23. You are absolutely right, implementing that forum from scratch is basically implementing stuff in PHP. If there is some interest, I indeed may write an in-depth blog entry, but for now I'll try to make it short (which probably does not work...). Let's start with a quick view on the five templates involved: forum-root well, this is the parent of everything. The template only contains the global welcome text but the associated php file enumerates any contained forum-group and creates the root layout. forum-group just a group around a couple of forums with its own descriptive bodytext forum-forum well, a forum containing the topics. The forum-forum nodes contain an additional "cache" for post and topic counts to provide a massive speedup when rendering forum-root. The counters are flagged with a timestamp, so they are updated on-the-fly only if required. forum-topic this node holds the post-list. In contrast to all other nodes which manage the content only by child-parent-relationship, this one has a page-table on the child node for the only purpose to see the thread also in admin. forum-post basically the post text with automated creation of title and name from current timestamp. Handling topic updates and user notifications was one of the first things implemented due to its expected complexity, but in the end it was rather easy and little efford with the right fields in place. topic-group, -forum and -topic nodes each has a page select field (holding PW user pages) which may be set or cleared by clicking on the grey wall to activate a "forum guard". Whenever there is a change beneath that node, the guard adds the topic to the per-user notification list (placed in the PW user template, which is more complex than usual this implementation). If there are pending notifications an additional button is displayed in the headline next to the user avatar: The user may check active notifications from that button and reading the topic will in turn clear that notification (remove the topic reference in the user's notification-list). Each user may choose to get informed by mail (standard WireMail) for pending notifications (html or text, various intervals, managed by LazyCron). The trick here is, that the user only get informed once per topic until he re-visited the forum to avoid flooding on active topics. Each visit is also recorded per-user to implement the updated-topic functionality. This is basically a topic/forum/group page select with the current timestamp in the PW user, updated topics are flagged with a bright lamp. https://forum.tom-productions.de/?f=test-forum&t=hallo-unglaublicher&p=1 Handling the post content is one of the more interesting and challenging features in this implementation. Mentions, for example, are detected when writing a post (regular @ syntax followed by the user name). This will simply add the post page to the user's notification list so it can be identified during regular processing. But there is more to explain in this screenshot. If someone replies to its own post, both are merged with that "Ergänzung" text beneath the ruler. That additional header is created during runtime from a data-ts field contained in the <hr> tag so it does survive even a later edit. While such an addition pushes the topic's modified timestamp, an edit doesn't. You may also note the phrase "externes Bild" next to an URL. This is a tribute to the european GDPR to not send the user's IP address to external servers without explicit grant. Clicking on that solid shield next to the cite icon will open a popup which has to be acknowledged. You may also notice the colored links in the user's signature, that's another point to avoid clicking on misleading links. If the link text contains the correct target server, its green, otherwise red (changed the signature for that screenshot). The color on the other hand does not qualify the linked content by any means... That's all done during runtime before actually displaying the post content along with replacing the usual emoticon shortcuts (learnt to love preg_replace_callback). Apropos Emoticons: To eliminate copyright issues I'm using regular Unicode emoticons which nicely pass through the PW engine and SQL, so emoticons will look differently depending on platform (Windows7 only shows black and white, for example). Apropos Signature: The signature actually is specified in markdown in an ordinary textarea field so I don't need to fiddle CKEditor into the LoginRegister module. Conversion into HTML is finally done using text formatter Markdown/Parsedown extra before the content has to pass my link and image filter. Well, there's so much more to tell (for example the CKEditor configuration), but that's for a later post... Ah, there is no magic behind the cite feature. It simply encloses the cited post into <blockquote> so the CKEditor opens with that block already filled.
  24. And now for something totally different... This project is neither about layout nor about fancy eye catchers. Its about a game from last century which celebrates its 30th anniversary this year and still has a some more or less active community. The idea behind the funky layout is to reutilize the original game graphics and fonts to obtain some corporate feeling, so it intentionally pixelates. On the other hand the bootstrap-based layout is modern enough to be responsive. The forum was originally founded in 2003 on ezBoard which morphed into YuKu around 2007 and ended in acquisition by Tapatalk in 2017. Most of its original flair had gone due to those provider changes and Tapatalk's ideas about collecting data didn't seem to be very compatible with the upcoming GDPR. Some action was required. My obvious first thought was, which forum system to choose. Second thought was, why not build a forum on ProcessWire? First hurdle to take was grabbing the existing forum content from Tapatalk, since they simply do not provide any kind of backup or export mechanism (at least not for free boards). Luckily nowadays we have jQuery and JavaScript which easily loads any website into a DOM tree which can be parsed and analyzed with little efford. Quickly we had one big structured JSON file with all forum content. It took another day to write a test importer and restore that content into a hierarchy of about 5000 ProcessWire pages to get an idea about the resulting performance and that looks pretty promising. In fact the final forum is still located on a shared host without much optimization and performs pretty well (response times around 100mSec except on root). Another goal, probably not possible at all with "standard" forum software, was the ability to play some background game music during the forum visit, so content update is entirely driven by AJAX which, in turn, nicely reduces data payload as well. From a technical standpoint the implementation uses the page fields created and modified to maintain its author and realize the typical "new posts" functionality, which needs some tweaking to keep everything in sync. PW Form Builder is used to simplify handling of input forms and configuration management of the frontend CKEditor (which is equipped with a dozen of plugins to provide emoticons, a per-user image repository and other fun stuff). Have fun https://forum.tom-productions.de/gameofrobot/ https://tom-productions.de/
×
×
  • Create New...