Jump to content

Luis

Members
  • Posts

    295
  • Joined

  • Last visited

  • Days Won

    5

Posts posted by Luis

  1. I handle purchases this way:

    I created a custom admin page which shows actual purchases.

    After purchase the system sends 2 emails. One to the customer with payment information and one to me to inform me about purchase, so far so usual. 

    Besides email notification the script creates a new page with customer credentials and a checkbox if paid or not. 

    The custom admin page lists those purchases and provides a button to set the purchase to paid. 

    When I set the purchase as paid the script generates a new page for the customer which contains the actual file and sends a mail to the customer with the link to this site inside. 

    After two weeks the generated customer page will be deleted.

    Thats it. 

  2. Table of contents

    • Introducing the App and author
    • Needs
    • First version in PHP/MySQL without any Framework
    • Why Processwire?
    • App Version 1.0

    Introducing the App and author

    Hi,

    my name is Luis and i´m a German based Web and Frontend Developer. 

    I started 2010 with my own Internetbusiness and noticed  at the very beginning of my business that it takes to much time to handle my accounting, invoices and clients.

    The main problem was that I needed for almost every task his own software solution, so the usual workflow in creating an invoice was something like open the CRM Software because the invoice software was good in creating invoices but bad in managing and searching clients, copy and paste the client into invoicing, create the invoice and handle it over to the accounting software.

    Not good at all...

    So I decided to create my own solution to fit my needs in the office management.

    Needs

    • Invoicemanagement and creation
    • Clientmanagement, very basic CRM
    • Accounting
    • Multi-User
    • Simple financial stats about the Keyfacts of my business  
    • possibility to export the data for my tax consultant
    • PHP / MySQL to work with it on intranet

    After pointing out my personal needs and writing down my usual workflow I started to develop the first version.

    First version in PHP/MySQL without any Framework

    In winter 2011/2012 I completed the very first version of my OMS (office management suite).

    momspreview4.pngmomspreview1.png

    The whole project was written in good old fashioned PHP from scratch.

    I´ve used this version till November 2012.

    Why Processwire?

    In mid 2012 I discovered Processwire and had no idea in how many ways this tool would change my life as webworker. 

    After playing around with PW and developing the first little sites I had a little talk with my tax consultant, she said that my financial reports are pretty good and help to save money. (less time, smaller invoice from her)

    Why not publish the tool?

    Well, at this point my app was solely written for my needs, without possibilities for an Multi-User environment or for use in an companies Intranet. 

    I finally decided to port the app to PW because of it´s flexibility, scalability and built-in user-roles. 

    I had to dig deeper into PW at this point to see if I really could. 

    Late 2012 I started porting the app in PW and was surprised how insanely fast developing could be. 

    The whole database structure was ported into PW Pages, no SQL query is done by the app itself.

    It was possible to recreate the core functionality in about 2 weeks, implementing the Login and Multi-User functionality took another week.

    WebApp Version 1.0

    https://youtu.be/PIgUMLZEcIU

    The app is now available for purchase @ www.misterui.de 

    * also Processwire with an own eCommerce Script

    • Like 16
  3. Good morning little app builder ninjas,

    As promised yesterday I will point you to the important forum posts on how you could build your own app in Processwire.

    Are we all seated?

    First we assume that our app is separated into two main parts.

    The Frontend with custom login and the Backend for App Administration and User Dashboard.

    Before we beginn follow this link: http://processwire.com/api/cheatsheet/

    Say hello to the Processwire API Cheatsheet made by Soma, whenever you meet Soma just give him a hug for this outstanding work.

    Why? I just hug my wife, girlfriend, boyfriend!

    Well the Cheatsheet would be definitely your best and maybe your most intimate friend during developing process. 

    Make yourself familiar with the Cheatsheet and make sure you activated the advanced view.

    Ok, lets beginn.

    Right before coding any line in our editor we have to think about our App.

    What should the App do?

    Which functionality do we need?

    Maybe you mockup your first design, but do not start to code!

    Think about your App, think about structuring your data, fields, templates,folder structure and ,believe me (really important), think about name conventions. 

    What does he mean with name conventions?

    A little example from one of my projects.

    The app handles three use cases, Frontend, Backend Administration and Client Dashboard, maybe a normal setting. 

    I started to think about naming template files and folders. 

    So I came up to the decision to name folders like this:

    includes-backend

      --admin

             --views

             --scripts

      --client

             --views

             --scripts

    includes-frontend

      --views

      --scripts

    Template files are named like this:

    backendHome.php

    backendMyData.php

    home.php

    homeNormalContent.php

    homeLogin.php

    Think about naming your page tree, this is maybe the first step in data structure you do.

    Why do we have to do all this, I just wanna code and cuddle together my App.

    Sure you could start this way, but do you know how large your app possibly could grow before really thought about?

    So, do yourself a favour and write down your thoughts. I´m working currently on a App which contains round about 300 Files of Script Logic and Output forms, editing without any logic in naming would definitely be a mess.

    Ok, we thought a lot of our App in theory, what now?

    We need a custom login!

    You find some usefull snippets and logic about login from frontend in this posts:

    http://processwire.com/talk/topic/1716-integrating-a-member-visitor-login-form/#entry15919

    http://processwire.com/talk/topic/107-custom-login/ (I really could recommend Renobirds login thoughts and his script)

    Read carefully through this posts, they contain almost everything you have to consider on frontend user management. 

    You are now on a point of using processwire where you definitely receive input from users, so think about security and make yourself familiar with $sanitizer.

    Never ever work with user generated data without sanitizing them!

    There are two main headlines you always have to remember:

    1st DO NOT SAVE PASSWORDS IN PLAIN TEXT IN YOUR APP

    2nd DO NOT TRUST INPUT YOU RECEIVE FROM USERS

    Ok, we finished our login and could setup a custom dashboard interface, but what next? My users have to generate some content and I don´t want to do this in my normal processwire administration dash. 

    Calm down little Ninja. 

    Ryan just gave you a strong and powerful tool. 

    He gave you Excalibur and named it just API. 

    Follow this links:

    http://processwire.com/talk/topic/352-creating-pages-via-api/ (creating content via api)

    http://processwire.com/talk/topic/296-programmed-page-creation-import-image-from-url/ (image handling)

    Thats it.  :ph34r:

    • Like 13
  4. Windows8.... I just reinstalled Win7 on my office PC, Win8 is not really my preffered  tool for office use, too much of swishes, blinks and no desktop on startup.

  5. Hello Processwire folks,

    today I want to show how to implement piwik into Processwire to show some specific site details to visitors or, if you create a special frontend login, for yourself. 

    First Step (preparation):

    What do we need?

    Well, to grab piwik data we need the piwik open source analytics suite. 

    Grab your copy here: http://piwik.org/

    Now copy piwik right into your Processwire folder, you get a folder structure like: piwik, site,wire

    next install piwik!

    After installation log into your piwik dashboard and setup your site, we need some information from piwik later in the tutorial, so just let the piwik dashboard open in the background.

    Now we have to think about data presentation.

    I´m currently working on a Webapp to let customers create their own Landing Pages and measure their performance, to show the data I´ve choosen morris.js a goodlooking javascript based on raphael.js and jQuery.

    So, we need jQuery. morris.js and raphael.js.

    jQuery : http://jquery.com/

    morris.js : http://www.oesmith.co.uk/morris.js/

    raphael.js : http://raphaeljs.com/

    Install all three scripts in your Processwire templates folder and dont forget to copy the provided .css file, too. 

    Second Step (Connect to the piwik API):

    To grab data from piwik we have to include the piwik API in our Processwire installation and we need some special settings to do.

    We need 2 informations about our piwik installation:

    1st our own Auth Token

    2nd the SiteID of our tracked page

    You could find your Auth Token in the piwik Dashboard. Just click on API in the head menu and there it is, in this little green box. 

    Now we need to know the site id of our page we want to show in our template files. 

    If you only setup one page in piwik the SiteId is 1, if you setup multiple sites click on "all websites" in the head menu now click on add new site. 

    Now you could see all your pages and their own site Id. 

    Remember where to find this informations, we need them in our next steps.

    Third Step (templating and API connection):

    Go to your PW Admin and create a new Template. 

    We don´t need any fields so far, so title and body would be enough, now create a new page with your new template. 

    Thats it on clicki bunti side, we now have to open our favorite ninja code editor. 

    Create a new file in your templates folder named like the template you created.

    Create a new file in a subfolder of your templates folder, maybe if exists in scripts or includes, wherever your include files are.

    Name this file analyticSettings.php

    This is our piwik API connector.

    Copy and paste the following code:

    
    <?php
    // if you don't include 'index.php', you must also define PIWIK_DOCUMENT_ROOT
    // and include "libs/upgradephp/upgrade.php" and "core/Loader.php"
    define('PIWIK_INCLUDE_PATH', realpath($config->paths->root.'/piwik'));
    define('PIWIK_USER_PATH', realpath($config->paths->root.'/piwik'));
    define('PIWIK_ENABLE_DISPATCH', false);
    define('PIWIK_ENABLE_ERROR_HANDLER', false);
    define('PIWIK_ENABLE_SESSION_START', false);
    
    require_once PIWIK_INCLUDE_PATH . "/index.php";
    require_once PIWIK_INCLUDE_PATH . "/core/API/Request.php";
    
    Piwik_FrontController::getInstance()->init();
    
    function piwikRequest($piwikSiteId,$piwikMethod,$piwikPeriod,$piwikDate,$piwikSegment,$piwikColumns, $piwikColumnsHide)
    {
      $piwikGetData = new Piwik_API_Request
      ('
        method='. $piwikMethod .'
        &idSite='. $piwikSiteId .'
        &period='. $piwikPeriod .'
        &date='. $piwikDate .'
        &format=php
        &serialize=0
        &token_auth=AUTH TOKEN
        &segment='.$piwikSegment.'
        &showColumns='. $piwikColumns .'
        &hideColumns='. $piwikColumnsHide .'
      ');
      $piwikGetData = $piwikGetData->process();
      return $piwikGetData;
    }
    
    ?>
    

    line 1 - 14 sets the paths to the piwik API and setup some error handling for piwik. 

    Enter your own Auth Token in line 26. 

    Thats it, connection to piwik allready done. 

    Now lets see how we grab our data.

    There is a function beginning in line 15. I named this little friend piwikRequest. 

    You could pass 7 values to our function to define which, how many, which date,period and method we want to request from piwik.

    $piwikSiteId = from which tracked page we need data. 

    $piwikMethod = which data method do we need? You could find a full list here: http://piwik.org/docs/analytics-api/reference/#toc-standard-api-parameters

    $piwikPeriod = day, year, moth, week

    $piwikDay= today, yesterday

    $piwikSegment = Segment of data, e.g. pageTitle==home

    $piwikColumnsShow = Only grab Data from this columns in the piwik database

    $piwikColumnsHide = Do not grab data from this columns 

    So, if we want to grab the visitor count from yesterday we could call our function like this:

    
    <?php echo piwikRequest('3','VisitsSummary.getVisits','day','yesterday' ?>
    

    3 = id of tracked site from piwik (I use piwik to track frontend, backend and the user created landing pages in its own site)

    VisitsSummary.getVisits = our API Method to tell piwik which data we need

    day = our period

    yesterday = well yes, data from yesterday ;)

    This request returns just a neat integer so there is no need to do additional logic, if we use methods providing more data the function returns an array which could be displayed by an print_r() or json_encode()

    Well our piwik connection is ready, now we want to show some data on our template file. 

    The Templating:

    Open your template file, make sure you included all needed files from jquery, morris and raphael. 

    Include on top of the page your piwik api connector file.

    Make sure that jquery, morris.js and raphael.js are included in this order and above the html code.

    Order:

    jQuery

    Rapaehl.js

    Morris.Js

    We now want to show 2 Donuts with 2 data values each. 

    Visits today and Yesterday.

    Total pageviews from this year, unique and all. 

    Copy and paste the following code to your template file:

    
    <h2>Visitors</h2>
    <div id="donut" style="height:200px;"></div>
    
    <h2>Page Views</h2>
    <div id="donut2" style="height:200px;"></div>
    <script>
    Morris.Donut({
      element: 'donut',
      data: [
        {label: "Yesterday", value: <?= piwikRequest('3','VisitsSummary.getVisits','day','yesterday') ?>},
        {label: "Today", value: <?= piwikRequest('3','VisitsSummary.getVisits','day','today' ) ?>},
      ]
    });
    Morris.Donut({
      element: 'donut2',
      data: [
        {label: "unique", value: <?= piwikRequest('3','Actions.get','year','yesterday',' ','nb_uniq_pageviews') ?>},
        {label: "all", value: <?= piwikRequest('3','Actions.get','year','yesterday',' ','nb_pageviews') ?>}
      ]
    });
    </script>
    

    We add 2 empty divs with some inline css. You could change this via a stylesheet. 

    In this 2 divs the morris script will draw a donut with the grabbed data from piwik.

    Right under the divs we are calling our morris.js and provide data from our piwikRequest function. 

    Thats all :)

    You could find all piwik methods, dates, periods and so on in the piwik api reference here: 

    http://piwik.org/docs/analytics-api/reference/#toc-standard-api-parameters

    post-782-0-93058800-1361717773_thumb.png

    • Like 6
  6. Hm,

    I added some more fields to look which save action is the problem. 

    the $user->save() works fine, no problems. 

    In case I edit any field of the corresponding page, related to the $user, the apache throws a 500 Internal but after looking into the edited page, every change has been saved properly.

    Strange

    EDIT:

    it works now, i dropped the $page->save() at bottom and save every field by his particular name in his own if statement like this

    if($input->post->clientactive && !$clientFolder->SettingsIsConfirmed)
        {      
            $clientFolder->SettingsIsConfirmed = 1;
            $clientFolder->save("SettingsIsConfirmed");
            $success = 1;
            $successActive = 1;        
        }
    
    
  7. <?php 
    
    //if our GET VAR is empty show the clients overview
    if(!$input->get->edituser)
    {
      include('./includes-backend/admin/scripts/clientsOverview.php');   
    }
    
    //check if our GET VAR is populated
    if($input->get->edituser)
    {
      //check if our GET VAR is an existing User, if so we show the User Profile else show the overview
      $client = $users->get($input->get->edituser);  
      if($client->id)
      {
        //fine, the submited id is an existing user, now grab the related user folder as Page Field Relation    
        $clientData = $client->ClientUserRelation;    
             
        $clientFolder = $pages->get($client->ClientUserRelation->id);
          
        //include the user profile with edit form     
        include('./includes-backend/admin/scripts/clientsEdit.php');
      }
      //submitted ID is not an existing user, so we show the overview
      else
      {
        include('./includes-backend/admin/scripts/clientsOverview.php'); 
      }
    }
    
    ?>
    

    snippet is included in clientsEdit

    dont be confused of $clientFolder, was a test if the page relation maybe caused the trouble, which dont

  8. Hey,

    while trying to build a user edit thingy I ran into a problem, which is confusing me.
    The form got 3 text inputs and 2 checkboxes, if I dont touch the checkboxes and just edit the text fields everything works fine.

    If I try to mark a box as checked, it looks like the script is running into a loop and finally throws an 500 Internal.
    As you can see the save() function is at the very bottom of the script and the script reaches this point as it saves the checkboxes just fine. 

    I dont get it. 

    Maybe someone could help.

      //check if the user edit form is submitted
      if($input->post->submit)
      {
        //set the outputformat to false in preparation to edit some changes
        //check if mail or pass will be changed, if not we dont need OF() false on $user
        if($input->post->clientpass || $input->post->clientemail)
        {
          $client->of(false);  
        }
        $clientFolder->of(false);
        
        //BEGIN OF PASSWORD EDIT -- First check if trying to edit the user pass
        if($input->post->clientpass)
        {
          //check if both, clientpass and clientconfirmpass matches
          if($input->post->clientpass == $input->post->clientpassconfirm)
          {
            //populate the tmp_pass instead of the pass field, in case the user reminds his password        
            $client->tmp_pass = $input->post->clientpass;  
            $successPass = 1;  
          }
          //passwords dont match, throw an error.
          else
          {
            $error = 1;
            $errorPass = 1;
          } 
        
        }
        //END OF PASSWORD EDIT
        
        //BEGIN E-MAIL EDIT -- First check if trying to edit the user mail
        if($input->post->clientemail)
        {
          $clientmail = $sanitizer->email($input->post->clientemail);
          //if sanitation fails the VAR is empty and we throw an error else save the mail
          if(!$clientmail)
          {
            $error = 1; 
            $errorMail = 1;        
          }
          //no errors and so we change Users mail
          else
          {
            $client->email = $clientmail;
            $successMail = 1;  
          }
        } 
        // END OF E-MAIL EDIT
        
        // BEGIN OF CHECKBOX EDIT -- We start with activating the clients subscription
        if($input->post->clientabo && !$clientFolder->SettingsIsPremium)
        {
            $clientFolder->SettingsIsPremium = 1;
            $success = 1;
            $successAbo = 1;        
        }
        //now we check if we wanna activate the Users Dashboard
        if($input->post->clientactive && !$clientFolder->SettingsIsConfirmed)
        {      
            $clientFolder->SettingsIsConfirmed = 1;
            $success = 1;
            $successActive = 1;        
        }    
        //if our checkboxes are empty we uncheck them in database
        if(!$input->post->clientabo && $clientFolder->SettingsIsPremium)
        {
            $clientFolder->SettingsIsPremium = 0;
            $success = 1;
            $successUnsubscribe = 1;        
        }
        //now we check if we wanna deactivate the User
        if(!$input->post->clientactive && $clientFolder->SettingsIsConfirmed)
        {     
            $clientFolder->SettingsIsConfirmed = 0;  
            $success = 1;
            $successDeactive = 1;        
        }  
        // END OF CHECKBOX EDIT 
        
        //now check which fields got changes and save the changes. 
        //first we check if mail or pass got changes, if so we save the $user and set OF to false after saving
        if($successMail == 1 || $successPass == 1)
          {
            $client->save();
            $client->of(true);  
          }
        //now we check if our checkboxes got changes and doing the same
        if($success == 1)
        {
          $clientFolder->save(); 
        }    
        $clientFolder->of(true); 
      }//<-- /if submit
    
    
×
×
  • Create New...