-
Posts
472 -
Joined
-
Last visited
-
Days Won
1
Everything posted by FrancisChung
-
Perhaps this is more what you're looking for ? http://faisalman.github.io/simple-excel-php/ I think I ran into some problems with the importCSV module (most likely user error on my part) so had to look for alternatives like SimpleExcel. Here's some code I've used on my project. It should be fairly straight forward and simple. public function ExecuteContent($file) { //TODO : Automate or Refactor this $_EOF = false; $_rowStart = 2; $_colTitle = 1; //A $_colMeta = 10;//J Meta Title = SEO Title $_colDesc = 11;//K $_colURL = 12;//L $_colURLnew = 13;//M $_colCanonical = 14;//N $_colAlt = 15;//O $_colKeywords = 16;//P $excel = new SimpleExcel('TSV'); $excel->parser->loadFile(__DIR__."/{$file}"); //$url = $excel->parser->getCell($_rowStart, $_colURL ); $row= $_rowStart; do { try { $title = $excel->parser->getCell($row, $_colTitle); $meta = $excel->parser->getCell($row, $_colMeta); $desc = $excel->parser->getCell($row, $_colDesc); $url = $excel->parser->getCell($row, $_colURL); $urlnew = $excel->parser->getCell($row, $_colURLnew); $canonical = $excel->parser->getCell($row, $_colCanonical); $alt = $excel->parser->getCell($row, $_colAlt); $keywords = $excel->parser->getCell($row, $_colKeywords); $internal = str_replace("http://sprachspielspass.de", '', $url); $page = wire(pages)->get("path=$internal"); //TODO: Error handling and logging if (!IsNullPage($page)) { $page->setOutputFormatting(false); set_time_limit(60); $page->title = $title; $page->seo_title = $meta; $page->seo_description = $desc; $page->url = $urlnew; $page->seo_canonical = $canonical; $page->image_alt = $alt; $page->seo_keywords = $keywords; try { $page->Save(); WriteLog("{$internal} saved"); } catch (\Exception $e) { WriteLog($e->getMessage() . " " . "{$page->title}" . " has errors"); } } else { WriteLog("{$internal} NOT FOUND!"); } //Manually deallocate $page as PHP's garbage collection is truly garbage. unset($page); /** * unset($title); * unset($meta); * unset($desc); * unset($urlnew); * unset($canonical); * unset($alt); * unset($keywords); * unset($internal); **/ $row++; } catch (\Exception $e) { $_EOF= true; } } while (!IsNullOrEmptyString($url) && (!$_EOF) ); /* $excel->convertTo('JSON'); $excel->writer->addRow(array('add', 'another', 'row')); $excel->writer->saveFile('example');*/ //unset($url); unset($excel); } Don't forget to reference the SimpleExcel.php file using either require_once or include_once. e.g. require_once(__DIR__."/../vendor/SimpleExcel/SimpleExcel.php");
-
It's not so much migrate or migration but just building upon what the processwire API provides. I really do appreciate the "freedom" the API provides, but I also sometimes wished there was some structure or guidance to follow (i.e. a Framework). You'll have to excuse me coming from a .NET background and still struggling with a lot of PHP's idiosyncrasies and gotchas. I'm not saying a Framework is useful for every scenarios, but for some scenarios it would be much quicker to get a site going if we could leverage reusable, tested components ala a Framework. I'm sure there are plenty here that have built their own framework(s) over the years. Would be nice to see an official or a collaborated effort.
-
<content> <p>Liebe Sonne komm gekrochen,</p> <p>denn mich friert` s an meine Knochen.</p> <p>Liebe Sonne, komm gerennt,</p> <p>denn mich friert` s an meine Händ.</p> </content> This is the content field I'm trying to update as currently represented in the XML file
-
I certainly agree with your Helper Module sentiments. I would actually go one step further and say a framework built on the PW API would be awesome as I sometimes find myself spending a lot of time trying to get certain tasks done, something a Framework could have easily mitigated. I tried to incorporate your code and I got it working for most part. I have a problem where I'm trying to populate a TextArea field from the XML file. $p->content = $xml->content; No errors but no data populated either. I'm guessing I may have to do some sort of casting or conversion? Has anyone got any experience or ideas on this?
-
API access to another site's object and data?
FrancisChung replied to FrancisChung's topic in API & Templates
Thanks fbg13 for the quick reply. It looks like I need to upgrade to PW3 to access this. If I did a local PW3 installation, copied the pages that I need from a copy of the Live DB to our Testing and deployed that DB back to PW 2.7.x instance, can any one see problems with that? Are the DBs backwards compatible, meaning PW2 would have no problems with any potential new fields that might be present in a DB that is PW3 versioned. I don't really want to roll fwd to PW3 this release window, if I can help it.- 3 replies
-
- api
- multi site
-
(and 4 more)
Tagged with:
-
It dawned on me as I'm trying to write some code to synch between 2 Processwire sites that it would be handy to be able to access another site's object and data via the Processwire API. I'm guessing it hasn't been considered so far, most likely because of security concerns? It appears to me the only way that is currently possible is to have a Single Database, Multi site setup? https://processwire.com/api/modules/multi-site-support/
- 3 replies
-
- api
- multi site
-
(and 4 more)
Tagged with:
-
PW on Dash FTW +1
-
I agree with you on the difficulty in trying to create something that will handle all scenarios. Always quicker to build something simple and custom fit. I think the difficulty lies in how to identify and deal with complex and compound data types, whether it is built by the user or introduced by module(s) the site is using. Is it straight forward to access those types using the API, for example? (I assume Yes but you never know) Also, if there are any new types introduced to PW Ecosystem, then it will have to retrospectively be able to handle it so you'll always be catching up. Probably the correct way to write something generic is to use Reflection and infer capabiltiies and attributes of your target objects, ala how PW does with its API documentation (Btw, how cool is that? Self documenting APIs! Sehr Guile!) https://processwire.com/blog/posts/processwire-3.x-api-reference/ .
-
Bernhard, thanks for the quick response and the code! Sehr Danke! I'll repurpose it for my situation and let you know how I went. If I have time, perhaps I could even try and make a more general purpose module that syncs between 2 instances.
-
Hi, I was wondering if there's an alternative ways of doing this other than using Migrator? Has there been a new module out that allows this? Or is it possible via API to get pages from one site, programatically go through each fields and create + save down to a new page on another site?
-
Packt Publishing is also giving an ebook away each day. https://www.packtpub.com/packt/offers/free-learning
- 3 replies
-
- 1
-
-
- syncfusion
- free
-
(and 2 more)
Tagged with:
-
No worries!
- 3 replies
-
- syncfusion
- free
-
(and 2 more)
Tagged with:
-
Hi, I posted a link to Free Books earlier and it dawned on me belatedly I should post this too. Basically I was looking for some free components to use with ASP.NET MVC and came across Syncfusion's Community License program. I've used Syncfusion's suite of components many moons ago when I was working in Finance, and whilst all these component suites do have a bit of a learning curve they do provide a lot of components and robust functionality out of the box that you can leverage. It's unheard of that a well established company like this would provide a free, community license when they could easily charge 1500-2000USD for a license but I'm guessing they must be losing market share to their competitors like Infragistics, DevExpress, Telerik etc and this is a bid to claw some back. Again, a lot of the things lean towards Microsoft .NET technologies but there's certain things that might be of interest like the Javascript controls for Web/Mobile as well as some Excel/Word/PDF/Powerpoint libraries and Data Science library. And calling a .NET/C# method in a DLL/Class from php is possible using this https://github.com/david-garcia-garcia/netphp instead of http://php.net/manual/en/class.dotnet.php which only allows .NET 3.5 or below. Enjoy!
-
- 1
-
-
- free controls
- free components
-
(and 3 more)
Tagged with:
-
I came across this section again recently and thought I would share. It's geared a little more towards Microsoft stuff but there will be something for everyone here. Enjoy https://www.syncfusion.com/resources/techportal/ebooks
- 3 replies
-
- 4
-
-
- syncfusion
- free
-
(and 2 more)
Tagged with:
-
Testing with Phpunit, Processwire & PHPStorm
FrancisChung replied to FrancisChung's topic in Tutorials
Test Leveraging: One of the advantages of setting up your tests like this is that you can easily create tests for other sites by merely creating a subclass and defining the URL of the new site you want to test. class WebFingerspieleContentUATest extends WebFingerspieleContentTest { protected function setUp() { $this->site = "http://finger-spiele.com"; } protected function tearDown() { } } Also note that in my earlier post, Test Structure, I've organised the tests separately per site. So it's easy to run tests or a set of tests on one or multiple sites. It certainly saved me a great deal of time testing during UAT, Live deployment .... Final Notes: 1) The way I've structured is by no means the best or even right(?) way for you. I would like to hear suggestions or alternative ways of structuring your tests. 2) The Selenium test framework is not always up to date with the latest browser updates, so there's a chance that your browser that you're testing does not launch. As time of writing, I'm aware of a problem with Firefox and maybe Chrome as well. It certainly wasn't the case when I was using it extensively. Unfortunately, I don't have a good workaround of this except perhaps rolling back your browser to a last known working version. 3) I should add that you need to have the Selenium server running in the background for the tests to work. java -jar selenium-server-standalone-2.50.1.jar 4) For chrome, I think you need a chromewebdriver in your Selenium folder and execute the following java -Dwebdriver.chrome.driver="/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome" -jar selenium-server-standalone-2.53.0.jar 5) This concludes the mini tutorial. I hope it was informative to some one out there, and please leave some comments. Would love some feedback. -
Testing with Phpunit, Processwire & PHPStorm
FrancisChung replied to FrancisChung's topic in Tutorials
Anatomy of a Test (Part 2): Now let's dive in a little and examine each of the functions to give you a better idea of what's going on. protected function setUp() { $this->site="http://localhost"; } setUp: This function is called by Phpunit (note the lowercase Camel spelling, as it will break if not spelt like this) to setup your test fixtures. In a nutshell, this is the place to setup any dependencies for the tests. This is a function you should implement for each Test class. I use this to mainly specify the URL of the site I'm going to test. As you will see later, I can easily reuse this test on other sites using this feature. More info on fixtures can be found here --> https://phpunit.de/manual/current/en/fixtures.html public function testSafari() { $browser = RemoteWebDriver::create('http://localhost:4444/wd/hub', DesiredCapabilities::safari()); $this::TestPageTitle($browser); $browser->close(); $browser->quit(); $browser = null; } public function testFirefox() { $browser = RemoteWebDriver::create('http://localhost:4444/wd/hub', DesiredCapabilities::firefox()); $this::TestPageTitle($browser); $browser->close(); $browser = null; } public function testChrome() { $browser = RemoteWebDriver::create('http://localhost:4444/wd/hub', DesiredCapabilities::chrome()); $this::TestPageTitle($browser); $browser->close(); $browser = null; } test<Browser>: Any functions with a "test" prefix (note lowercase spelling here) will be called by the Phpunit framework, so you can see I have 3 test functions for the framework to call. Each of my "external" test functions represent a test case corresponding to a particular browser. Obviously you don't have to set it up like this, but my choices were somewhat dictated by my dependency on Php-webdriver. The first line of code is invoking the Php-webdriver and passing it the location of the <xxx> and telling it what properties (DesiredCapabilities) you want. Once this is successful, I call some internal test functions which I will go through next. private function TestData() { return array( array("{$this->site}/fingerspiele/alle-fingerspiele/10-kleine-zappelmaenner/", 'Zehn kleine Zappelmänner | Fingerspiel | Sprachspielspass.de'), array("{$this->site}/fingerspiele/alle-fingerspiele/der-osterhase/", 'Der Osterhase | Fingerspiel für Kinder | Sprachspielspass.de'), array("{$this->site}/fingerspiele/alle-fingerspiele/weiss-wie-schnee/",'Weiß wie Schnee | Fingerspiel Sommer | Sprachspielspass.de'), array("{$this->site}/fingerspiele/alle-fingerspiele/ein-kleines-auto/", 'Ein kleines Auto | Fingerspiel | Sprachspielspass.de'), array("{$this->site}/fingerspiele/alle-fingerspiele/es-regnet-ganz-sacht/", 'Es regnet ganz sacht | Fingerspiel | Sprachspielspass.de'), array("{$this->site}/fingerspiele/alle-fingerspiele/das-ist-der-daumen/", 'Das ist der Daumen | Fingerspiel | Sprachspielspass.de'), array("{$this->site}/fingerspiele/alle-fingerspiele/plumps-und-platsch/", "Plumps und platsch | Fingerspiel | Sprachspielspass.de"), array("{$this->site}/fingerspiele/alle-fingerspiele/fuenf-engelchen/", 'Fünf Engelchen | Fingerspiel Winter | Sprachspielspass.de'), array("{$this->site}/fingerspiele/alle-fingerspiele/erst-kommt-die-schnecke/", 'Erst kommt die Schnecke | Fingerspiel | Sprachspielspass.de') ); // } private function TestPageTitle($browser) { $data = $this::TestData(); //TestFactory::PageTitleTest($data, $browser, $this); foreach($data as $testItem) { $url = $testItem[0]; $expected = $testItem[1]; $browser->get($url); $this->assertContains($expected, $browser->getTitle()); } } Test<TestName>: These functions should represent each unit of testing you're interested in. So in my example, I'm testing to see a web page has to expected page title. So TestPageTitle will loop through a set of test URLs and expected titles and report any failures using the assertContains. $this->assertContains($expected, $browser->getTitle()); By all means, there are other ways to assert your tests other than assertContains, so feel free to explore them. -
Testing with Phpunit, Processwire & PHPStorm
FrancisChung replied to FrancisChung's topic in Tutorials
Understand where you're coming from. Unfortunately, a lot of my classes actually have a simple output method and that method would output what is seen in the browser in its entirety so the smallest testable unit for most of my classes is also the largest. I've changed or removed terminology to remove any ambiguity or confusion. -
Any PHPStorm users here who uses phpUnit? Setup question
FrancisChung replied to FrancisChung's topic in General Support
FYI, I have written a guide for those looking to get Phpunit to work with Phpstorm. -
Testing with Phpunit, Processwire & PHPStorm
FrancisChung replied to FrancisChung's topic in Tutorials
Anatomy of a Test (Part 1): Now that we have a test structure in place, you might be asking yourself "what sort of tests should I be writing?" In general, you should start writing tests that would test the most important aspect of your site / system. For a CMS like Processwire, that would be tests that would cover Content Integrity for example, as content is king in a CMS. Tests that would cover navigation could be another example as growing content means growing navigational possibilities. You can use tools to determine how much of your written unit tests actually test your site/system, but test coverage is beyond the scope of this post. Let's look at example content unit test to see what's actually inside. <?php /** * Created by PhpStorm. * User: FrancisChung * Date: 09/03/16 * Time: 19:06 */ namespace Test; use Facebook\WebDriver\Remote\DesiredCapabilities; use Facebook\WebDriver\Remote\RemoteWebDriver; //use Facebook\WebDriver\WebDriverCapabilities; require_once(__DIR__."/../../../composer/vendor/autoload.php"); class WebFingerspieleContentTest extends \PHPUnit_Framework_TestCase { protected $site; protected function setUp() { $this->site="http://localhost"; } public function testSafari() { $browser = RemoteWebDriver::create('http://localhost:4444/wd/hub', DesiredCapabilities::safari()); $this::TestPageTitle($browser); $browser->close(); $browser->quit(); $browser = null; } public function testFirefox() { $browser = RemoteWebDriver::create('http://localhost:4444/wd/hub', DesiredCapabilities::firefox()); $this::TestPageTitle($browser); $browser->close(); $browser = null; } public function testChrome() { $browser = RemoteWebDriver::create('http://localhost:4444/wd/hub', DesiredCapabilities::chrome()); $this::TestPageTitle($browser); $browser->close(); $browser = null; } private function TestData() { return array( array("{$this->site}/fingerspiele/alle-fingerspiele/10-kleine-zappelmaenner/", 'Zehn kleine Zappelmänner | Fingerspiel | Sprachspielspass.de'), array("{$this->site}/fingerspiele/alle-fingerspiele/der-osterhase/", 'Der Osterhase | Fingerspiel für Kinder | Sprachspielspass.de'), array("{$this->site}/fingerspiele/alle-fingerspiele/weiss-wie-schnee/",'Weiß wie Schnee | Fingerspiel Sommer | Sprachspielspass.de'), array("{$this->site}/fingerspiele/alle-fingerspiele/ein-kleines-auto/", 'Ein kleines Auto | Fingerspiel | Sprachspielspass.de'), array("{$this->site}/fingerspiele/alle-fingerspiele/es-regnet-ganz-sacht/", 'Es regnet ganz sacht | Fingerspiel | Sprachspielspass.de'), array("{$this->site}/fingerspiele/alle-fingerspiele/das-ist-der-daumen/", 'Das ist der Daumen | Fingerspiel | Sprachspielspass.de'), array("{$this->site}/fingerspiele/alle-fingerspiele/plumps-und-platsch/", "Plumps und platsch | Fingerspiel | Sprachspielspass.de"), array("{$this->site}/fingerspiele/alle-fingerspiele/fuenf-engelchen/", 'Fünf Engelchen | Fingerspiel Winter | Sprachspielspass.de'), array("{$this->site}/fingerspiele/alle-fingerspiele/erst-kommt-die-schnecke/", 'Erst kommt die Schnecke | Fingerspiel | Sprachspielspass.de') ); // } /** * @param $browser */ private function TestPageTitle($browser) { $data = $this::TestData(); //TestFactory::PageTitleTest($data, $browser, $this); foreach($data as $testItem) { $url = $testItem[0]; $expected = $testItem[1]; $browser->get($url); $this->assertContains($expected, $browser->getTitle()); } } } Now the 2 use statements (DesiredCapabilities & Webdriver) are needed to access the Php-webdriver that we will be using to interact with Selenium. The require_once(__DIR__."/../../../composer/vendor/autoload.php") statement is to reference the Phpunit test framework that we installed via Composer (I got stuck on here for a while). Your test also needs to derive from \PHPUnit_Framework_TestCase as you can see in the above example. This is all the dependencies you need to write a Phpunit test for Processwire that runs on Phpstorm. In the next post (Part 2 of this topic), I will go through each method and explain their purpose and function. -
Holy ..... That was quick
- 2 replies
-
- processwire brand
- processwire
-
(and 4 more)
Tagged with:
-
I ran across this by chance .... http://www.redbubble.com/people/smdnetau/works/9425499-processwire?grid_pos=1&p=iphone-case ... and was wondering if Ryan or anyone else had ever had the idea of making some Processwire T-shirts? I would get one ...
- 2 replies
-
- processwire brand
- processwire
-
(and 4 more)
Tagged with:
-
Testing with Phpunit, Processwire & PHPStorm
FrancisChung replied to FrancisChung's topic in Tutorials
Test Structure: Now that we've setup PHPUnit with PHPStorm, let's talk about how to structure and setup your tests. This is where people can vary in their strategy and approaches quite a bit. Would be great to see how others approach it. It's probably a good idea to isolate your tests away from your code. For example I've put my tests in /site/templates/php/tests I've structured my tests into 3 basic folders that represent the different servers my website resides on. They are core, uat and live. The core folder contains the basic core versions of my tests. They also point to my local dev server for testing purposes. The uat and live folder contains derived versions of these core tests that points to UAT & Live servers respectively. The idea with having 3 seperate folders is that you can run isolated tests on each servers easily during testing and deployment phases. Hopefully it's all been straight forward so far. I will go into detail about the tests themselves in the next post. -
Testing with Phpunit, Processwire & PHPStorm
FrancisChung replied to FrancisChung's topic in Tutorials
PHPUnit configuration in PHP Storm : This is where I got stuck for a while. The documentation surrounding this was unclear or unspecific at best. The trick was to configure PHPStorm (in preferences) to use a Custom Autoloader that you specify and also define a default configuration file, both which were not apparent to me with the available documentation I could find. The Custom Autoloader needs to point to autoload.php for Composer (hence my earlier pre-requisite of installing Phpunit via Composer). The default configuration file is a XML file that defines certain basic variables that PHPUnit in order to function. The one I've attached is a fairly basic one, with custom testsuites defined being the main difference. The custom testsuites elements will become apparent once I explain how I structured my tests. For those interested in a detailed breakdown of the XML config, there are some detailed documentation at https://phpunit.de/manual/current/en/appendixes.configuration.html. I've attached a screenshot of my preferences phpunit.xml -
I'm writing this to give back something to the community that has given so much up front over the past year. I noticed there's hardly any discussion about testing in these forums so I decided to write this quick primer to get some discussion going. I'm by no means an expert on phpunit or selenium but I had to jump through a few hoops to get it working (especially with PHPStorm), so I thought I figured I should share my experiences with the community. Also, I'm hoping non Phpstorm users can still pick something up useful in this post. Prerequisites : It is assumed Phpunit (https://phpunit.de/) is installed via Composer, Selenium (http://www.seleniumhq.org/) and Php-webdriver for Selenium (https://github.com/facebook/php-webdriver) is preinstalled. For Phpstorm users, there's a fairly detailed installation and unit testing instructions here (https://www.jetbrains.com/help/phpstorm/2016.1/testing.html) I found some parts of it leaving me with unanswered questions, so I'm hoping this post will supplement any questions that you might encounter. Rather than writing a single monolithic post, I will write several posts covering different topics.
-
Bootstrapping Processwire in PHPUnit
FrancisChung replied to FrancisChung's topic in General Support
Actually, I had to reinstall MAMP Pro as I realised it was causing other issues. Unfortunately, I saw your post after I figured it out Marcus. (Could have saved me hours of pain). But thanks for the post. Definitely will come in handy for other users stumbling here,.