Expat-IT Tech Bits

Home

Contact

Links

Search this site:

Categories:

/ (287)
  Admin/ (122)
    Apache/ (10)
      HTTPS-SSL/ (4)
      PHP/ (3)
      performance/ (2)
    Cherokee/ (1)
    LAN/ (4)
    LVM/ (6)
    Monitoring/ (2)
      munin/ (2)
    SSH/ (6)
    SSL/ (1)
    Samba/ (1)
    VPN-options/ (6)
      OpenVPN/ (1)
      SSH-Proxy/ (3)
      Tinc/ (1)
      sshuttle/ (1)
    backups/ (17)
      SpiderOak/ (1)
      backuppc/ (5)
      dirvish/ (1)
      misc/ (6)
      rdiff-backup/ (1)
      rsync/ (1)
      unison/ (2)
    commandLine/ (24)
      files/ (8)
      misc/ (10)
      network/ (6)
    crontab/ (1)
    databases/ (15)
      MSSQL/ (2)
      MySQL/ (8)
      Oracle/ (3)
      PostgreSQL/ (1)
    dynamicDNS/ (2)
    email/ (11)
      Dovecot/ (1)
      deliverability/ (1)
      misc/ (1)
      postfix/ (7)
      puppet/ (1)
    iptables/ (3)
    tripwire/ (1)
    virtualization/ (9)
      VMware/ (1)
      virtualBox/ (8)
  Coding/ (14)
    bash/ (1)
    gdb/ (1)
    git/ (3)
    php/ (5)
    python/ (4)
      Django/ (2)
  Education/ (1)
  Hosting/ (27)
    Amazon/ (18)
      EBS/ (3)
      EC2/ (10)
      S3/ (1)
      commandline/ (4)
    Godaddy/ (2)
    NearlyFreeSpeech/ (3)
    Rackspace/ (1)
    vpslink/ (3)
  Linux/ (30)
    Android/ (1)
    Awesome/ (3)
    CPUfreq/ (1)
    China/ (2)
    Debian/ (8)
      APT/ (3)
      WPA/ (1)
    audio/ (1)
    encryption/ (3)
    fonts/ (1)
    misc/ (6)
    remoteDesktop/ (1)
    router-bridge/ (3)
  SW/ (45)
    Micro$soft/ (1)
    browser/ (2)
      Chrome/ (1)
      Firefox/ (1)
    business/ (28)
      Drupal/ (9)
      KnowledgeTree/ (6)
      Redmine/ (2)
      SugarCRM/ (7)
      WebERP/ (2)
      WordPress/ (1)
      eGroupware/ (1)
    chat/ (1)
    email/ (1)
    fileSharing/ (2)
      btsync/ (1)
      mldonkey/ (1)
    graphics/ (2)
    research/ (2)
    website/ (6)
      blog/ (6)
        blosxom/ (3)
        rss2email/ (1)
        webgen/ (1)
  Security/ (15)
    IMchat/ (2)
    circumvention/ (2)
    cryptoCurrency/ (1)
    e-mail/ (4)
    greatFirewall/ (1)
    hacking/ (1)
    password/ (1)
    privacy/ (2)
    skype/ (1)
  Services/ (1)
    fileSharing/ (1)
  TechWriting/ (1)
  xHW/ (14)
    Lenovo/ (1)
    Motorola_A1200/ (2)
    Thinkpad_600e/ (1)
    Thinkpad_a21m/ (3)
    Thinkpad_i1300/ (1)
    Thinkpad_x24/ (1)
    USB_audio/ (1)
    scanner/ (1)
    wirelessCards/ (2)
  xLife/ (17)
    China/ (9)
      Beijing/ (5)
        OpenSource/ (3)
    Expatriation/ (1)
    Vietnam/ (7)

Archives:

  • 2016/07
  • 2016/05
  • 2016/02
  • 2016/01
  • 2015/12
  • 2015/11
  • 2015/06
  • 2015/01
  • 2014/12
  • 2014/11
  • 2014/10
  • 2014/09
  • 2014/07
  • 2014/04
  • 2014/02
  • 2014/01
  • 2013/12
  • 2013/10
  • 2013/08
  • 2013/07
  • 2013/06
  • 2013/05
  • 2013/04
  • 2013/02
  • 2013/01
  • 2012/12
  • 2012/10
  • 2012/09
  • 2012/08
  • 2012/07
  • 2012/06
  • 2012/05
  • 2012/04
  • 2012/03
  • 2012/01
  • 2011/12
  • 2011/11
  • 2011/10
  • 2011/09
  • 2011/08
  • 2011/07
  • 2011/06
  • 2011/05
  • 2011/04
  • 2011/02
  • 2010/12
  • 2010/11
  • 2010/10
  • 2010/09
  • 2010/08
  • 2010/07
  • 2010/06
  • 2010/05
  • 2010/04
  • 2010/03
  • 2010/02
  • 2010/01
  • 2009/12
  • 2009/11
  • 2009/10
  • 2009/09
  • 2009/08
  • 2009/07
  • 2009/06
  • 2009/05
  • 2009/04
  • 2009/03
  • 2009/02
  • 2009/01
  • 2008/12
  • 2008/11
  • 2008/10
  • 2008/09
  • Subscribe XML RSS Feed

    Creative Commons License
    This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.
    PyBlosxom

    This site has no ads. To help with hosting, crypto donations are accepted:
    Bitcoin: 1JErV8ga9UY7wE8Bbf1KYsA5bkdh8n1Bxc
    Zcash: zcLYqtXYFEWHFtEfM6wg5eCV8frxWtZYkT8WyxvevzNC6SBgmqPS3tkg6nBarmzRzWYAurgs4ThkpkD5QgiSwxqoB7xrCxs

    Tue, 14 May 2013


    /Coding/php: Geolocation with PHP

    You will probably want:

    apt-get install php5-geoip geoip-database

    Then a command-line script is this easy:

    <?php // if (geoip_db_avail(GEOIP_COUNTRY_EDITION)) // print geoip_database_info(GEOIP_COUNTRY_EDITION); $country = geoip_country_code_by_name('any-ip-address'); switch ($country) { case 'US': echo "100"; break; case 'CN': echo "200"; break; case 'HK': echo "300"; break; } ?>

    And you might want to do something like this for a bit of web code:

    <?php $clientIP = getenv("REMOTE_ADDR"); echo 'Client IP = ' . $clientIP . '<br>'; $country = geoip_country_code_by_name($clientIP); echo $country . ' price = '; switch ($country) { case 'DE': echo "500"; break; case 'IL': echo "400"; break; case 'US': echo "100"; break; case 'CN': echo "200"; break; case 'HK': echo "300"; break; } ?>

    If the geoip database provided by the geoip-database package is too old (three years already in Ubuntu Lucid, for example!) then remove it and download the database manually:

    wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz

    Unzip it, and then add this line to /etc/php5/conf.d/geoip.ini:

    geoip.custom_directory = /path/to/directory/containing/GeoIP.dat/

    posted at: 09:55 | path: /Coding/php | permanent link to this entry

    Tue, 04 Aug 2009


    /Coding/php: A Simple SugarCRM API Class

    This should give anyone needing to use the SugarCRM API a quickstart:

    <?php /* * class_sugarconnect.php * * Copyright 2009 Clayton Koenig <ckoeni@gmail.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ ?> <?php class sugarapi{ // connection variables var $client; // soap client var $session_id; // identifier for this login session var $user_id; // of logged in user // connection settings for SOAP var $options = array( "location" => 'https://url.of.your.sugarcrm.installation.com/sugarcrm/soap.php', "uri" => 'http://www.sugarcrm.com/sugarcrm', "trace" => 1 ); //user authentication array (version is SOAP version) private $user_auth = array(); function __construct() { // must use constructor b/c of MD5 function call $this->user_auth = array( "user_name" => 'sugaruserid', "password" => MD5('yourpasswd'), "version" => '.01' ); } // arrays for input into sugarCRM modules var $contact = array(); var $account = array(); function login() { $this->client = new SoapClient(NULL, $this->options); $response = $this->client->login($this->user_auth); // var_dump($response); // just in case you need it $this->session_id = $response->id; printf("<p></p>session id = ". $this->session_id); $this->user_id = $this->client->get_user_id($this->session_id); printf("<p>" . $this->user_auth['user_name'] . ' has a GUID of ' . $this->user_id . "<p>"); } function getModules() { $response = $this->client->get_available_modules($this->session_id); foreach ($response->modules as $i => $value) { printf($response->modules[$i] . "<br>"); } } function getModuleFields($module) { $response = $this->client->get_module_fields($this->session_id, $module); printf("<p>Module " . $response->module_name .' has the following fields:' . "<p>"); printf("<table><tr>" . "<td><u>Name</td><td><u>Type</td><td><u>Label</td>" . "<td><u>Required</td><td><u>Options</td>" . "</tr>"); foreach ($response->module_fields as $i => $value) { printf('<tr><td>' . $response->module_fields[$i]->name . '</td>' . '<td>' . $response->module_fields[$i]->type . '</td>' . '<td>' . $response->module_fields[$i]->label . '</td>' . '<td>' . $response->module_fields[$i]->required . '</td>' . '<td>' . $response->module_fields[$i]->options . '</td></tr>'); } printf('</table>'); } function setContactField($fieldname, $fieldvalue) { $this->contact[] = array("name" => $fieldname,"value" => $fieldvalue); } function storeContact() { // into sugar's Contacts database $response = $this->client->set_entry($this->session_id, 'Contacts', $this->contact); var_dump($response); } } ?>

    And the following is a simple example of how to use the above class to create a simple contact record with a name and an e-mail address, and store it in Sugar's Contacts database.

    <?php include("class_sugarapi.php"); $sugar = new sugarapi(); $sugar->login(); // populate the contact array $sugar->setContactField('last_name', 'Bloke2'); $sugar->setContactField('email1', 'xyz@wxy.net'); // var_dump($sugar->contact); $sugar->storeContact(); // to Contacts database ?>

    To find out all the possible fields in the Contacts database, use this script:

    <?php include("class_sugarapi.php"); $sugar = new sugarapi(); $sugar->login(); // look what modules sugar exposes $sugar->getModules(); // look in more detail at the fields in a module $sugar->getModuleFields('Accounts'); ?>

    Many thanks to this post[1] for getting me on my way.

    [1] http://systemsconsciousness.com/2009/04/10/sugarcrm-soap-examples/

    posted at: 04:14 | path: /Coding/php | permanent link to this entry

    Wed, 29 Apr 2009


    /Coding/php: Accessing the KnowledgeTree API

    KnowledgeTree[1] is a very popular server-based Open Source document management system. Something that some users (like me, or rather my clients) need to do is allow certain people to add or manipulate documents in KnowledgeTree without having to have a login ID and knowledge of the KnowledgeTree user interface. Enter the API, and a little custom PHP scripting....

    Oddly enough, I found at least three different documents on the wiki[2] that seemed to talk about three different approaches to using the API. Oddly (should I say suspiciously?) because the level of detail was just enough to be interesting, but just short of being useful. Ie. for two of them, I just could not figure it out. I even saw a post on the KnowledgeTree forum asking for more detail / a concrete example (me too! me too!) and the only reply was a curt link to one of the near useless wiki pages that I have already mentioned. And needless to say, my own post was ignored. Whats up? (Some conspiratorial possibilities come to mind....)

    The only API approach that I have been able to get working is the "REST web service framework"[3], which, for better or worse, only works as of the currently bleeding edge KnowledgeTree version 3.6.0 (will NOT work with current stable 3.5.4a). [3] is also sorely lacking in detail, but in combination with a little code surfing in

    knowledgetree/ktwebservice/webservice.php

    I was able to divine what was needed to get it working. Here I will hopefully provide some missing detail for Google to find....

    One can of course play with the KnowledgeTree REST web service through a browser, as the means of communication with the server is via POST parameters attached to the server URL. This is also a good way to see the exact format of the XML response the server gives back.

    To achieve the same result with PHP one must use libcurl through the PHP curl extension[4]. Since [4] is also a little skimpy on detail, [5] is a very useful supplement. To cut to the chase, I created a function as follows:

    <?php function curlPost($site, $fields){ $ch = curl_init(); // initialize curl handle curl_setopt($ch, CURLOPT_URL,$site); // set url to post to curl_setopt($ch, CURLOPT_FAILONERROR, 1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);// allow redirects curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); // return into a variable curl_setopt($ch, CURLOPT_TIMEOUT, 9); // times out after 10s curl_setopt($ch, CURLOPT_POST, 1); // set POST method curl_setopt($ch, CURLOPT_POSTFIELDS, $fields); $answer = curl_exec($ch); // run the whole process // print_r(curl_getinfo($ch)); // echo "\n\ncURL error number:" .curl_errno($ch); // echo "\n\ncURL error:" . curl_error($ch); curl_close($ch); return $answer; } ?>

    $site is the REST URL of the KnowledgeTree server, and $fields are the POST parameters that are to go along with it. This function simply POSTs these parameters to the URL (exactly the same as entering $site?$fields into your web browser).

    Here is a concrete and currently working example of how to get the contents of the KnowledgeTree root directory:

    <?php $url = 'https://www.server.com/kt-dms-oss-3.6.0/ktwebservice/KTWebService.php'; require_once('funCurlPost.php'); // ************************** // Login // ************************** $postfields = "method=login&password=123456&username=admin"; $response = curlPost($url, $postfields); $xml = new SimpleXMLElement($response); if( $xml->status_code != 0 ){ echo 'Error - authentication failed: ' . $xml->message; } else { $session_id = $xml->results; echo "Login successful, session ID = " . $session_id; } // *********************************** // List contents of root folder (id=1) // *********************************** $postfields = "method=get_folder_contents&session_id=$session_id&folder_id=1"; $response = curlPost($url, $postfields); $xml = new SimpleXMLElement($response); echo "<p>Get root folder contents:<br>"; if( $xml->status_code != 0 ){ echo 'Error - get_folder_contents failed: ' . $xml->message; } else { // print_r($xml); // to see data structure echo "<p>folder ID = " . $xml->results->folder_id . "<br>"; echo "folder name = " . $xml->results->folder_name . "<br>"; echo "folder path = " . $xml->results->full_path . "<p>"; foreach ($xml->results->items->item as $value) { echo "item type = " . $value->item_type . " "; echo "item ID = " . $value->id . " "; echo "item name = " . $value->filename . "<br>"; } } // *********************************** // Logout // *********************************** $postfields = "method=logout&session_id=$session_id"; $response = curlPost($url, $postfields); $xml = new SimpleXMLElement($response); echo "<p>Logging out....<br>"; if( $xml->status_code != 0 ){ echo 'Error - get_folder_contents failed: ' . $xml->message; } else { echo 'successful!'; } ?>

    The key point is that there were three operations in the above script, with three corresponding POST strings:

    OperationPOST string
    Loginlogin&password=123456&username=admin
    List Directory get_folder_contents&session_id=$session_id&folder_id=1
    Logoutmethod=logout&session_id=$session_id

    And something else that is already working -- to add a document to KnowledgeTree, use this POST string:

    $document = "bodybg.jpg"; // located in /var/uploads

    $postfields = "method=add_document&session_id=$session_id&folder_id=1&title=$document&filename=$document&documenttype=Default&tempfilename=/vol/www/vsc/apps/kt-dms-oss-3.6.0/var/uploads/$document";

    [1] http://www.knowledgetree.com/
    [2] http://wiki.knowledgetree.com/
    [3] http://wiki.knowledgetree.com/REST_Web_Service
    [4] http://php.net/manual/en/book.curl.php
    [5] http://devzone.zend.com/article/1081-Using-cURL-and-libcurl-with-PHP

    posted at: 01:08 | path: /Coding/php | permanent link to this entry

    Tue, 21 Apr 2009


    /Coding/php: XML to Object Conversion

    In working with the KnowledgeTree API[2] I found that the response to my http posts to the API came back in the form of XML. I needed to get that XML into PHP-processable form, and a quite a bit of googling mostly turned up home-grown solutions, a lot of them referring to themselves as "xmltoarray" functions . Until I found the PHP-native solution, SimpleXMLElement[1]. Hopefully this post will help to push SimpleXMLElement a little higher in Google's search listings....

    Suppose I have a big junk of XML in string form, such as this response to a KnowledgeTree API directory listing:

    <response> <status_code>0</status_code> <message/> − <results> <folder_id>1</folder_id> <folder_name>Root Folder</folder_name> <full_path>/</full_path> − <items> − <item> <id>2</id> <item_type>F</item_type> <custom_document_no>n/a</custom_document_no> <oem_document_no>n/a</oem_document_no> <title>DroppedDocuments</title> <document_type>n/a</document_type> <filename>DroppedDocuments</filename> <filesize>n/a</filesize> <created_by>Administrator</created_by> <created_date>n/a</created_date> <checked_out_by>n/a</checked_out_by> <checked_out_date>n/a</checked_out_date> <modified_by>n/a</modified_by> <modified_date>n/a</modified_date> <owned_by>n/a</owned_by> <version>n/a</version> <is_immutable>n/a</is_immutable> <permissions>RWA</permissions> <workflow>n/a</workflow> <workflow_state>n/a</workflow_state> <mime_type>folder</mime_type> <mime_icon_path>folder</mime_icon_path> <mime_display>Folder</mime_display> <storage_path>n/a</storage_path> <items/> </item> − <item> <id>11</id> <item_type>F</item_type> <custom_document_no>n/a</custom_document_no> <oem_document_no>n/a</oem_document_no> <title>Public</title> <document_type>n/a</document_type> <filename>Public</filename> <filesize>n/a</filesize> <created_by>Administrator</created_by> <created_date>n/a</created_date> <checked_out_by>n/a</checked_out_by> <checked_out_date>n/a</checked_out_date> <modified_by>n/a</modified_by> <modified_date>n/a</modified_date> <owned_by>n/a</owned_by> <version>n/a</version> <is_immutable>n/a</is_immutable> <permissions>RWA</permissions> <workflow>n/a</workflow> <workflow_state>n/a</workflow_state> <mime_type>folder</mime_type> <mime_icon_path>folder</mime_icon_path> <mime_display>Folder</mime_display> <storage_path>n/a</storage_path> <items/> </item> − </items> </results> </response>

    in a variable called $response. Converting to a structured object is simply:

    $xml = new SimpleXMLElement($response);

    And then the object might be processed as follows:

    if( $xml->status_code != 0 ){ echo 'Error - operation failed: ' . $xml->message; } else { // print_r($xml); // to see data structure echo "<p>folder ID = " . $xml->results->folder_id . "<br>"; echo "folder name = " . $xml->results->folder_name . "<br>"; echo "folder path = " . $xml->results->full_path . "<p>"; foreach ($xml->results->items->item as $value) { echo "item type = " . $value->item_type . " "; echo "item ID = " . $value->id . " "; echo "item name = " . $value->filename . "<br>"; } }

    [1] http://php.net/manual/en/book.simplexml.php
    [2] http://wiki.knowledgetree.com/REST_Web_Service

    posted at: 06:27 | path: /Coding/php | permanent link to this entry

    Sat, 07 Mar 2009


    /Coding/php: Coding Conventions

    This[1] is, I think, an excellent and concise summary of PHP coding conventions, both for readability and for reducing load on the server. This is the first time I have heard of the advisability of avoiding double quotes, for instance.

    [1] http://www.weberp.org/ContributingtowebERP

    posted at: 00:54 | path: /Coding/php | permanent link to this entry