PHP और Google Sheets की मदद से, उपयोगकर्ता के योगदान वाला मैप बनाना

पामेला फ़ॉक्स, Google Maps API टीम
नवंबर 2007

मकसद

वेब पर, भौगोलिक क्षेत्रों और दिलचस्पी के हिसाब से कई कम्यूनिटी मौजूद हैं. जैसे, म्यूज़ियम, यूरोप के कैथेड्रल, स्टेट पार्क वगैरह पसंद करने वाले लोग. इसलिए, हमेशा एक ऐसे डेवलपर (आपकी तरह!) की ज़रूरत होती है जो एक ऐसा सिस्टम बना सके जहां उपयोगकर्ता, मैप में जियोटैग की गई जगहों का योगदान दे सकें. हम यहां ठीक यही काम करेंगे. इस लेख के आखिर तक, आपके पास एक ऐसा सिस्टम होगा जिसमें उपयोगकर्ता रजिस्टर कर सकेंगे, लॉगिन कर सकेंगे, और जियोटैग की गई जगहों को जोड़ सकेंगे. सिस्टम, फ़्रंट-एंड के लिए AJAX, सर्वर-साइड स्क्रिप्टिंग के लिए PHP, और स्टोरेज के लिए Google Sheets का इस्तेमाल करेगा. अगर आपको डेटा स्टोर करने के लिए MySQL डेटाबेस का इस्तेमाल करने की आदत है, तो यहां दिए गए कोड में आसानी से बदलाव करके, MySQL डेटाबेस बैकएंड का इस्तेमाल किया जा सकता है.

इस लेख में, इन चरणों के बारे में बताया गया है:


स्प्रेडशीट सेट अप करना

हम इस सिस्टम के लिए, Google Sheets का इस्तेमाल करके सारा डेटा सेव करेंगे. हमें दो तरह का डेटा सेव करना है: उपयोगकर्ता खाते की जानकारी और उपयोगकर्ता की ओर से जोड़े गए स्थान. इसलिए, हम हर तरह के डेटा के लिए एक-एक वर्कशीट बनाएंगे. हम लिस्ट फ़ीड का इस्तेमाल करके, वर्कशीट के साथ इंटरैक्ट करेंगे. यह वर्कशीट की पहली लाइन पर निर्भर करता है, जिसमें कॉलम के लेबल होते हैं. इसके बाद की हर लाइन में डेटा होता है.

docs.google.com पर जाएं और नई स्प्रेडशीट बनाएं. डिफ़ॉल्ट वर्कशीट का नाम बदलकर "Users" करें. इसके बाद,"user," "password," और "session" नाम के कॉलम बनाएं. इसके बाद, एक और शीट जोड़ें. इसका नाम बदलकर "Locations" करें. साथ ही,"user," "status," "lat," "lng," और "date" नाम के कॉलम बनाएं. इसके अलावा, अगर आपको मैन्युअल तरीके से काम नहीं करना है, तो यह टेंप्लेट डाउनलोड करें और इसे फ़ाइल->इंपोर्ट कमांड के ज़रिए Google Spreadsheets में इंपोर्ट करें.

उपयोगकर्ता खाते की जानकारी को निजी रखना ज़रूरी है. यह सिर्फ़ स्प्रेडशीट के मालिक (आप) को दिखती है. वहीं, उपयोगकर्ता की जोड़ी गई जगहों को सार्वजनिक तौर पर दिखने वाले मैप पर दिखाया जाएगा. अच्छी बात यह है कि Google Sheets में, यह तय किया जा सकता है कि स्प्रेडशीट की कौनसी वर्कशीट सार्वजनिक होंगी और कौनसी निजी (डिफ़ॉल्ट) रहेंगी. "जगहें" वर्कशीट को पब्लिश करने के लिए, "पब्लिश करें" टैब पर क्लिक करें. इसके बाद, "अभी पब्लिश करें" पर क्लिक करें. "अपने-आप फिर से पब्लिश करें" चेकबॉक्स पर सही का निशान लगाएं. इसके बाद, "कौनसे हिस्से?" ड्रॉप-डाउन में, "सिर्फ़ 'जगहें' शीट" चुनें. सही विकल्प, नीचे दिए गए स्क्रीनशॉट में दिखाए गए हैं:

Zend GData फ़्रेमवर्क के साथ काम करना

Google Spreadsheets API, CRUD ऑपरेशनों के लिए एक एचटीटीपी इंटरफ़ेस उपलब्ध कराता है. जैसे, पंक्तियां वापस पाना, पंक्तियां डालना, पंक्तियां अपडेट करना, और पंक्तियां मिटाना. Zend Framework, एपीआई (और अन्य GData API) के ऊपर एक PHP रैपर उपलब्ध कराता है, ताकि आपको रॉ एचटीटीपी ऑपरेशन लागू करने के बारे में चिंता न करनी पड़े. Zend Framework के लिए PHP 5 ज़रूरी है.

अगर आपके पास Zend फ़्रेमवर्क पहले से नहीं है, तो इसे डाउनलोड करें और अपने सर्वर पर अपलोड करें. यह फ़्रेमवर्क यहां उपलब्ध है: http://framework.zend.com/download/gdata.

आपको Zend लाइब्रेरी को शामिल करने के लिए, अपने PHP include_path में बदलाव करना चाहिए. ऐसा करने के कई तरीके हैं. यह इस बात पर निर्भर करता है कि आपके पास सर्वर पर एडमिन के कितने अधिकार हैं. लाइब्रेरी का इस्तेमाल करने वाली किसी भी PHP फ़ाइल में, require स्टेटमेंट के ऊपर यह लाइन जोड़ें:

ini_set("include_path", ".:/usr/lib/php:/usr/local/lib/php:../../../library/");

इसे आज़माने के लिए, demos/Zend/Gdata फ़ोल्डर में कमांड लाइन पर यह डालकर, स्प्रेडशीट का डेमो चलाएं:

php Spreadsheet-ClientLogin.php --user=YourGMailUsername --pass=YourPassword

अगर यह काम करता है, तो आपको अपनी स्प्रेडशीट की सूची दिखेगी. अगर आपको कोई गड़बड़ी मिलती है, तो देखें कि आपका शामिल किया गया पाथ सही तरीके से सेट किया गया है या नहीं. साथ ही, यह भी देखें कि आपने PHP 5 इंस्टॉल किया है या नहीं.

ग्लोबल फ़ंक्शन बनाना

कम्यूनिटी मैप के लिए, हम जो भी PHP स्क्रिप्ट लिखेंगे उनमें सामान्य तौर पर शामिल किए जाने वाले फ़ंक्शन, वैरिएबल, और फ़ाइलें इस्तेमाल की जाएंगी. हम इन सभी को एक फ़ाइल में रखेंगे.

फ़ाइल की शुरुआत में, Zend लाइब्रेरी को शामिल करने और लोड करने के लिए ज़रूरी स्टेटमेंट होंगे. ये स्टेटमेंट, Spreadsheets-ClientLogin.php के उदाहरण से लिए गए हैं.

इसके बाद, हम उन कॉन्स्टेंट को तय करेंगे जिनका इस्तेमाल सभी फ़ाइलों में किया जाएगा: स्प्रेडशीट की और दो वर्कशीट आईडी. अपनी स्प्रेडशीट की जानकारी देखने के लिए, उसे खोलें. इसके बाद, "पब्लिश करें टैब" पर क्लिक करें और फिर "पब्लिश करने के अन्य विकल्प" पर क्लिक करें. फ़ाइल फ़ॉर्मैट ड्रॉप-डाउन सूची से "ATOM" चुनें. इसके बाद, "यूआरएल जनरेट करें" पर क्लिक करें. आपको कुछ ऐसा दिखेगा:

http://spreadsheets.google.com/feeds/list/o16162288751915453340.4016005092390554215/od6/public/basic

स्प्रेडशीट की, "/list/," के बाद आने वाली लंबी अल्फ़ान्यूमेरिक स्ट्रिंग होती है. वहीं, वर्कशीट आईडी, इसके बाद आने वाली तीन वर्णों की स्ट्रिंग होती है. दूसरी वर्कशीट का आईडी ढूंढने के लिए, "कौनसी शीट?" ड्रॉप-डाउन से दूसरी शीट चुनें.

इसके बाद, हम तीन फ़ंक्शन बनाएंगे: setupClient, getWkshtListFeed, और printFeed. setupClient में, हम अपना Gmail उपयोगकर्ता नाम और पासवर्ड सेट करेंगे. साथ ही, ClientLogin की मदद से पुष्टि करेंगे और Zend_Gdata_Spreadsheets ऑब्जेक्ट दिखाएंगे. getWkshtListFeed में, हम दी गई स्प्रेडशीट कुंजी और वर्कशीट आईडी के लिए, स्प्रेडशीट की सूची वाला फ़ीड दिखाएंगे. इसमें स्प्रेडशीट क्वेरी (लिंक) का विकल्प भी होगा. printFeed फ़ंक्शन को Spreadsheets-ClientLogin.php के उदाहरण से लिया गया है. यह डीबग करने में आपके लिए मददगार हो सकता है. यह फ़ीड ऑब्जेक्ट को इनपुट के तौर पर लेगा और उसे स्क्रीन पर प्रिंट करेगा.

इसके लिए इस्तेमाल किया गया PHP कोड यहां दिया गया है (communitymap_globals.php):

<?php
ini_set("include_path", ".:/usr/lib/php:/usr/local/lib/php:../../../library/");
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
Zend_Loader::loadClass('Zend_Gdata_Spreadsheets');
Zend_Loader::loadClass('Zend_Http_Client');

define("SPREADSHEET_KEY", "o16162288751915453340.4016005092390554215");
define("USER_WORKSHEET_ID", "od6");
define("LOC_WORKSHEET_ID", "od7");
 
function setupClient() {
  $email = "your.name@gmail.com";
  $password = "yourPassword";
  $client = Zend_Gdata_ClientLogin::getHttpClient($email, $password,
          Zend_Gdata_Spreadsheets::AUTH_SERVICE_NAME);
  $gdClient = new Zend_Gdata_Spreadsheets($client);
  return $gdClient;
}
 
function getWkshtListFeed($gdClient, $ssKey, $wkshtId, $queryString=null) {
  $query = new Zend_Gdata_Spreadsheets_ListQuery();
  $query->setSpreadsheetKey($ssKey);
  $query->setWorksheetId($wkshtId);
  if ($queryString !== null) {
    $query->setSpreadsheetQuery($queryString);
  }
  $listFeed = $gdClient->getListFeed($query);
  return $listFeed;
}
 
function printFeed($feed)
{
  print "printing feed";
  $i = 0;
  foreach($feed->entries as $entry) {
      if ($entry instanceof Zend_Gdata_Spreadsheets_CellEntry) {
         print $entry->title->text .' '. $entry->content->text . "\n";
      } else if ($entry instanceof Zend_Gdata_Spreadsheets_ListEntry) {
         print $i .' '. $entry->title->text .' '. $entry->content->text . "\n";
      } else {
         print $i .' '. $entry->title->text . "\n";
      }
      $i++;
  }
}
 
?>

नए उपयोगकर्ता को रजिस्टर करना

किसी नए उपयोगकर्ता को रजिस्टर करने के लिए, हमें टेक्स्ट फ़ील्ड और सबमिट बटन वाला एचटीएमएल पेज चाहिए. साथ ही, उपयोगकर्ता को स्प्रेडशीट में जोड़ने के लिए, PHP बैकएंड स्क्रिप्ट चाहिए.

PHP स्क्रिप्ट में, हम सबसे पहले ग्लोबल स्क्रिप्ट को शामिल करते हैं. इसके बाद, GET वैरिएबल से उपयोगकर्ता नाम और पासवर्ड की वैल्यू पाते हैं. इसके बाद, हम एक Spreadsheets क्लाइंट सेट अप करते हैं. साथ ही, उपयोगकर्ताओं की वर्कशीट के लिए सूची फ़ीड का अनुरोध करते हैं. इसमें एक क्वेरी स्ट्रिंग होती है. इससे नतीजे सिर्फ़ उन लाइनों तक सीमित रहते हैं जहां उपयोगकर्ता नाम कॉलम, स्क्रिप्ट में पास किए गए उपयोगकर्ता नाम के बराबर होता है. अगर हमें लिस्ट फ़ीड के नतीजे में कोई भी लाइन नहीं मिलती है, तो हम यह मानकर आगे बढ़ सकते हैं कि पास किया गया उपयोगकर्ता नाम यूनीक है. सूची वाले फ़ीड में कोई लाइन डालने से पहले, हम कॉलम की वैल्यू का एक असोसिएटिव ऐरे बनाते हैं: उपयोगकर्ता नाम, PHP के sha1 फ़ंक्शन का इस्तेमाल करके पासवर्ड का एन्क्रिप्शन, और सेशन के लिए फ़िलर वर्ण. इसके बाद, हम स्प्रेडशीट क्लाइंट पर insertRow को कॉल करते हैं. इसमें हम असोसिएटिव ऐरे, स्प्रेडशीट की, और वर्कशीट आईडी पास करते हैं. अगर लौटाया गया ऑब्जेक्ट ListFeedEntry है, तो हम Success! मैसेज दिखाते हैं.

इसके लिए इस्तेमाल किया गया PHP कोड यहां दिया गया है (communitymap_newuser.php):

<?php
 
require_once 'communitymap_globals.php';
 
$username = $_GET['username'];
$password = $_GET['password'];
 
$gdClient = setupClient();
 
$listFeed = getWkshtListFeed($gdClient, SPREADSHEET_KEY, USER_WORKSHEET_ID, ('user='.$username));
$totalResults = $listFeed->totalResults;
if ( $totalResults != "0") {
  // Username already exists
  exit;
}
 
$rowArray["user"] = $username;
$rowArray["password"] = sha1($password);
$rowArray["session"] = "a";
 
$entry = $gdClient->insertRow($rowArray, SPREADSHEET_KEY, USER_WORKSHEET_ID);
if ($entry instanceof Zend_Gdata_Spreadsheets_ListEntry) {
  echo "Success!";
}
?>

रजिस्ट्रेशन पेज पर, हम Maps API को शामिल कर सकते हैं, ताकि हम इसके XMLHttpRequest रैपर फ़ंक्शन GDownloadUrl का इस्तेमाल कर सकें. जब उपयोगकर्ता सबमिट बटन पर क्लिक करता है, तो हमें टेक्स्ट फ़ील्ड से उपयोगकर्ता नाम और पासवर्ड मिल जाएगा. हम उनकी वैल्यू से एक पैरामीटर स्ट्रिंग बनाएंगे. इसके बाद, स्क्रिप्ट यूआरएल और पैरामीटर पर GDownloadUrl को कॉल करेंगे. हम संवेदनशील जानकारी भेज रहे हैं. इसलिए, हम GDownloadUrl के HTTP POST वर्शन का इस्तेमाल कर रहे हैं. इसके लिए, हम पैरामीटर को यूआरएल में जोड़ने के बजाय, तीसरे आर्ग्युमेंट के तौर पर भेज रहे हैं. कॉलबैक फ़ंक्शन में, हम यह देखेंगे कि जवाब सही है या नहीं. इसके बाद, उपयोगकर्ता को सही मैसेज दिखाएंगे.

नीचे, रजिस्ट्रेशन पेज (communitymap_register.htm) के सैंपल का स्क्रीनशॉट और कोड दिखाया गया है:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
  <title> Community Map - Register/Login </title>

  <script src="http://maps.google.com/maps?file=api&v=2&key=abcdef"
      type="text/javascript"></script>
  <script type="text/javascript">

  function register() {
    var username = document.getElementById("username").value;
    var password = document.getElementById("password").value;
    var url = "communitymap_newuser.php?";
    var params = "username=" + username + "&password=" + password;
    GDownloadUrl(url, function(data, responseCode) {
      if (data.length > 1) {
        document.getElementById("message").innerHTML = "Successfully registered." + 
          "<a href='communitymap_login.htm'>Proceed to Login</a>.";
      } else {
        document.getElementById("message").innerHTML = "Username already exists. Try again.";
      }
    }, params);
  }

  </script>

  </head>
  <body>
  <h1>Register for Community Map</h1>
  <input type="text" id="username">
  <input type="password" id="password">

  <input type="button" onclick="register()" value="Register">
  <div id="message"></div>
  </body>
</html>

किसी उपयोगकर्ता के तौर पर लॉग इन करना

उपयोगकर्ताओं को हमारे सिस्टम में साइन इन करने की अनुमति देने के लिए, हमें उपयोगकर्ता के लिए एक एचटीएमएल पेज की ज़रूरत होगी. इससे उपयोगकर्ताओं को अपना उपयोगकर्ता नाम और पासवर्ड डालने के लिए कहा जा सकेगा. साथ ही, हमें एक PHP स्क्रिप्ट की भी ज़रूरत होगी. इससे लॉगिन की जानकारी की पुष्टि की जा सकेगी, सेशन आईडी बनाया जा सकेगा, और उसे वापस लॉगिन पेज पर भेजा जा सकेगा, ताकि कुकी सेट की जा सके. उपयोगकर्ता, सेशन कुकी की मदद से अगले पेजों पर लॉग इन रहेगा.

PHP स्क्रिप्ट में, हम सबसे पहले ग्लोबल स्क्रिप्ट को शामिल करते हैं. इसके बाद, GET वैरिएबल से उपयोगकर्ता नाम और पासवर्ड की वैल्यू पाते हैं. इसके बाद, हम एक Spreadsheets क्लाइंट सेट अप करते हैं. साथ ही, उपयोगकर्ताओं की वर्कशीट के लिए सूची फ़ीड का अनुरोध करते हैं. इसमें एक क्वेरी स्ट्रिंग होती है. इससे नतीजे सिर्फ़ उन लाइनों तक सीमित रहते हैं जहां उपयोगकर्ता नाम कॉलम, स्क्रिप्ट में पास किए गए उपयोगकर्ता नाम के बराबर होता है.

हम यह देखेंगे कि दिखाई गई लाइन में, पास किए गए पासवर्ड का हैश, स्प्रेडशीट में सेव किए गए हैश से मेल खाता है या नहीं. अगर ऐसा है, तो हम md5, uniqid, और rand फ़ंक्शन का इस्तेमाल करके एक सेशन आईडी बनाएंगे. इसके बाद, हम स्प्रेडशीट में मौजूद लाइन को सेशन से अपडेट करेंगे. अगर लाइन अपडेट हो जाती है, तो हम उसे स्क्रीन पर दिखाएंगे.

इसके लिए इस्तेमाल किया गया PHP कोड यहां दिया गया है (communitymap_loginuser.php):

<?php
 
require_once 'communitymap_globals.php';
 
$username = $_POST['username'];
$password = $_POST['password'];
 
$gdClient = setupClient();
 
$listFeed = getWkshtListFeed($gdClient, SPREADSHEET_KEY, USER_WORKSHEET_ID, ('user='.$username));
 
$password_hash = sha1($password);
$row = $listFeed->entries[0];
$rowData = $row->getCustom();
foreach($rowData as $customEntry) {
  if ($customEntry->getColumnName()=="password" && $customEntry->getText()==$password_hash) {
    $updatedRowArray["user"] = $username;
    $updatedRowArray["password"] = sha1($password);
    $updatedRowArray["session"] = md5(uniqid(rand(), true));
    $updatedRow = $gdClient->updateRow($row, $updatedRowArray); 
    if ($updatedRow instanceof Zend_Gdata_Spreadsheets_ListEntry) {
      echo $updatedRowArray["session"];
    }
  }
}
?>

लॉगिन पेज पर, हम Maps API को फिर से शामिल कर सकते हैं, ताकि हम इसके XMLHttpRequest रैपर फ़ंक्शन GDownloadUrl का इस्तेमाल कर सकें. जब उपयोगकर्ता 'सबमिट करें' बटन पर क्लिक करता है, तो हमें टेक्स्ट फ़ील्ड से उपयोगकर्ता नाम और पासवर्ड मिल जाएगा. इसके बाद, हम क्वेरी पैरामीटर के साथ स्क्रिप्ट यूआरएल बनाएंगे और स्क्रिप्ट यूआरएल पर GDownloadUrl को कॉल करेंगे. कॉलबैक फ़ंक्शन में, हम सेशन आईडी वाली एक कुकी सेट करेंगे. यह आईडी स्क्रिप्ट से मिलता है. अगर कोई आईडी नहीं मिलता है, तो हम गड़बड़ी का मैसेज दिखाएंगे. setCookie फ़ंक्शन, cookies.js से आता है. यह w3c JavaScript ट्यूटोरियल पर आधारित है: http://www.w3schools.com/js/js_cookies.asp.

नीचे, लॉगिन पेज (communitymap_login.htm) के नमूने के लिए स्क्रीनशॉट और कोड दिखाया गया है:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>

  <title>Community Map - Login</title>
      <script src="http://maps.google.com/maps?file=api&v=2&key=abcdef"
      type="text/javascript"></script>
  <script src="cookies.js" type="text/javascript"></script>
  <script type="text/javascript">

  function login() {
    var username = document.getElementById("username").value;
    var password = document.getElementById("password").value;
    var url = "communitymap_loginuser.php?username=" + username + "&password=" + password;
    GDownloadUrl(url, function(data, responseCode) {
      if (data.length > 1) {
        setCookie("session", data, 5);
      } else {
        document.getElementById("nessage").innerHTML = "Error. Try again.";
      }
    });
  }

  </script>
  </head>
  <body>

  <h1>Login for Community Map</h1>

  <input type="text" id="username">
  <input type="password" id="password">
  <input type="button" onclick="login()" value="Login">
  <div id="message"></div>
  </body>
</html>

लोगों को मैप में जगहों की जानकारी जोड़ने की सुविधा देना

किसी उपयोगकर्ता को हमारे मैप में जगहें जोड़ने की अनुमति देने के लिए, हमें उपयोगकर्ता के लिए उपलब्ध एचटीएमएल पेज की ज़रूरत होगी. इससे उपयोगकर्ता, जगह की जानकारी दे पाएगा. साथ ही, हमें दो PHP स्क्रिप्ट की ज़रूरत होगी. पहली स्क्रिप्ट यह जांच करेगी कि उपयोगकर्ता ने हमारी सेट की गई कुकी के ज़रिए लॉग इन किया है या नहीं. दूसरी स्क्रिप्ट, जगह की जानकारी को जगहों की वर्कशीट में जोड़ेगी.

यहां दी गई पहली PHP स्क्रिप्ट में यह देखा जाता है कि उपयोगकर्ता लॉग इन है या नहीं. इसमें सबसे पहले ग्लोबल स्क्रिप्ट को शामिल किया जाता है. इसके बाद, GET वैरिएबल से सेशन की वैल्यू मिलती है. इसके बाद, हम एक स्प्रेडशीट क्लाइंट सेट अप करते हैं. साथ ही, क्वेरी स्ट्रिंग के साथ उपयोगकर्ताओं की वर्कशीट के लिए सूची फ़ीड का अनुरोध करते हैं, ताकि नतीजे सिर्फ़ उन लाइनों तक सीमित रहें जहां सेशन कॉलम, स्क्रिप्ट में पास की गई सेशन वैल्यू के बराबर हो. इसके बाद, हम उस फ़ीड की कस्टम एंट्री (वे एंट्री जो हमारे कॉलम हेडर से मेल खाती हैं) को दोहराते हैं. साथ ही, अगर कोई उपयोगकर्ता नाम मौजूद है, तो उस सेशन के लिए उपयोगकर्ता का नाम प्रिंट करते हैं.

इसके लिए इस्तेमाल किया गया PHP कोड यहां दिया गया है (communitymap_checksession.php):

<?php

require_once 'communitymap_globals.php';

$session = $_GET['session'];

$gdClient = setupClient();

$listFeed = getWkshtListFeed($gdClient, SPREADSHEET_KEY, USER_WORKSHEET_ID, ('session='.$session));

if ( count($listFeed->entries) > 0) {
  $row = $listFeed->entries[0];
  $rowData = $row->getCustom();
  foreach($rowData as $customEntry) {
    if ($customEntry->getColumnName()=="user") {
      echo $customEntry->getText();
    }
  }
}
?>

दूसरी PHP स्क्रिप्ट में, उपयोगकर्ता को जगह की जानकारी जोड़ने की सुविधा मिलती है. इसमें हम सबसे पहले communitymap_checksession.php से कोड को दोहराते हैं, ताकि यह पक्का किया जा सके कि उपयोगकर्ता अब भी लॉग इन है और मान्य है. इसके बाद, जब हमें उपयोगकर्ताओं की शीट से मान्य उपयोगकर्ता नाम मिलता है, तो हमें GET वैरिएबल से जगह, अक्षांश, और देशांतर की वैल्यू मिलती हैं. हम उन सभी वैल्यू को एक असोसिएटिव ऐरे में डालते हैं. साथ ही, PHP के date() फ़ंक्शन का इस्तेमाल करके "date" वैल्यू भी जोड़ते हैं, ताकि हमें पता चल सके कि उपयोगकर्ता ने जगह कब जोड़ी. हम उस असोसिएटिव ऐरे, स्प्रेडशीट के मुख्य कॉन्स्टेंट, और जगहों की जानकारी वाली वर्कशीट के आईडी कॉन्स्टेंट को insertRow फ़ंक्शन में पास करते हैं. इसके बाद, अगर स्प्रेडशीट में नई जगह के लिए कोई लाइन जोड़ी जाती है, तो हम "Success" आउटपुट करते हैं. अगर आपको इस चरण में गड़बड़ी का मैसेज मिलता है, तो ऐसा कॉलम हेडर के नामों के मेल न खाने की वजह से हो सकता है. एसोसिएटिव ऐरे में मौजूद कुंजियां, स्प्रेडशीट की कुंजी और वर्कशीट आईडी से तय की गई वर्कशीट में मौजूद कॉलम हेडर से मेल खानी चाहिए.

इसके लिए इस्तेमाल किया गया PHP कोड यहां दिया गया है (communitymap_addlocation.php):

<?php

require_once 'communitymap_globals.php';

$session = $_GET['session'];

$gdClient = setupClient();

$listFeed = getWkshtListFeed($gdClient, SPREADSHEET_KEY, USER_WORKSHEET_ID, ('session='.$session));

if ( count($listFeed->entries) > 0) {
  $row = $listFeed->entries[0];
  $rowData = $row->getCustom();
  foreach($rowData as $customEntry) {
    if ($customEntry->getColumnName()=="user") {
      $user = $customEntry->getText();
    }
  }

  $place = $_GET['place'];
  $lat = $_GET['lat'];
  $lng = $_GET['lng'];
  $rowArray["user"] = $user;
  $rowArray["place"] = $place;
  $rowArray["lat"] = $lat;
  $rowArray["lng"] = $lng;
  $rowArray["date"] = date("F j, Y, g:i a");
  $entry = $gdClient->insertRow($rowArray, SPREADSHEET_KEY, LOC_WORKSHEET_ID);
  if ($entry instanceof Zend_Gdata_Spreadsheets_ListEntry) {
    echo "Success!\n";
  }
}

?>

जगह की जानकारी जोड़ने वाले पेज पर, हम Maps API को फिर से शामिल कर सकते हैं, ताकि हम GDownloadUrl का इस्तेमाल कर सकें और मैप बना सकें. पेज लोड होने के बाद, हम cookies.js से getCookie फ़ंक्शन का इस्तेमाल करके, सेशन की वैल्यू वापस पाते हैं. अगर सेशन स्ट्रिंग शून्य है या खाली है, तो हम गड़बड़ी का मैसेज दिखाते हैं. अगर ऐसा नहीं है, तो हम map.checksession.php पर GDownloadUrl को कॉल करते हैं और सेशन भेजते हैं. अगर इससे उपयोगकर्ता नाम मिल जाता है, तो हम उपयोगकर्ता को स्वागत मैसेज दिखाते हैं. साथ ही, जगह जोड़ने का फ़ॉर्म दिखाते हैं और मैप लोड करते हैं. इस फ़ॉर्म में, पते के लिए टेक्स्ट फ़ील्ड, मैप, और जगह के नाम, अक्षांश, और देशांतर के लिए टेक्स्ट फ़ील्ड शामिल होते हैं. अगर उपयोगकर्ता को जगह के अक्षांश/देशांतर के बारे में पहले से जानकारी नहीं है, तो वह फ़ॉर्म में अपना पता डालकर और "सबमिट करें" दबाकर, उसे जियोकोड कर सकता है. इससे Map API के GClientGeocoder को कॉल भेजा जाएगा. अगर उसे पता मिल जाता है, तो वह मैप पर एक मार्कर लगा देगा. साथ ही, अक्षांश/देशांतर वाले टेक्स्ट फ़ील्ड में अपने-आप जानकारी भर देगा.

जब उपयोगकर्ता को सही जानकारी मिल जाती है, तो वह "जगह की जानकारी जोड़ें" बटन दबा सकता है. इसके बाद, JavaScript में हमें उपयोगकर्ता, जगह, अक्षांश, और देशांतर की वैल्यू मिलेंगी. हम इन्हें GDownloadUrl की मदद से, communitymap_addlocation.php स्क्रिप्ट को भेजेंगे.

अगर स्क्रिप्ट से 'सफल' मैसेज मिलता है, तो हम स्क्रीन पर 'सफल' मैसेज दिखाएंगे.

जगह की जानकारी जोड़ने के लिए बने सैंपल पेज (communitymap_addlocation.htm) का स्क्रीनशॉट और कोड यहां दिया गया है:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
    <title>Community Map - Add a Place!</title>

    <script src="http://maps.google.com/maps?file=api&v=2.x&key=abcdef" type="text/javascript"></script>
    <script src="cookies.js" type="text/javascript"></script>
    <script type="text/javascript">
    //<![CDATA[

    var map = null;
    var geocoder = null; 
    var session = null;

    function load() {
      session = getCookie('session');
      if (session != null && session != "") {
        url = "communitymap_checksession.php?session=" + session;
        GDownloadUrl(url, function(data, responseCode) {
          if (data.length > 0) {
            document.getElementById("message").innerHTML = "Welcome " + data;
            document.getElementById("content").style.display = "block";
            map = new GMap2(document.getElementById("map"));
            map.setCenter(new GLatLng(37.4419, -122.1419), 13);
            geocoder = new GClientGeocoder();
          }
        });
      } else {
        document.getElementById("message").innerHTML = "Error: Not logged in.";
      }
    }

    function addLocation() {
      var place = document.getElementById("place").value;
      var lat = document.getElementById("lat").value;
      var lng = document.getElementById("lng").value;

      var url = "communitymap_addlocation.php?session=" + session + "&place=" + place +
                "&lat=" + lat + "&lng=" + lng;
      GDownloadUrl(url, function(data, responseCode) {
        GLog.write(data);
        if (data.length > 0) {
          document.getElementById("message").innerHTML = "Location added.";
        }
      });
    }

    function showAddress(address) {
      if (geocoder) {
        geocoder.getLatLng(
          address,
          function(point) {
            if (!point) {
              alert(address + " not found");
            } else {
              map.setCenter(point, 13);
              var marker = new GMarker(point, {draggable:true});
              document.getElementById("lat").value = marker.getPoint().lat().toFixed(6);
              document.getElementById("lng").value = marker.getPoint().lng().toFixed(6);

              map.addOverlay(marker);
              GEvent.addListener(marker, "dragend", function() {
                document.getElementById("lat").value = marker.getPoint().lat().toFixed(6);
                document.getElementById("lng").value = marker.getPoint().lng().toFixed(6);
	      });
            }
          }
        );
      }
    }
    //]]>

    </script>

  </head>

  <body onload="load()" onunload="GUnload()">
   <div id="message"></div>
   <div id="content" style="display:none">

   <form action="#" onsubmit="showAddress(this.address.value); return false">
        <p>
        <input type="text" size="60" name="address" value="1600 Amphitheatre Pky, Mountain View, CA" />
        <input type="submit" value="Geocode!" />

    </form>
      </p>

      <div id="map" style="width: 500px; height: 300px"></div>
 
 	Place name: <input type="text" size="20" id="place" value="" />
	<br/>
 	Lat: <input type="text" size="20" id="lat" value="" />
	<br/>

 	Lng: <input type="text" size="20" id="lng" value="" />

        <br/>
	<input type="button" onclick="addLocation()" value="Add a location" />
    </form>
    </div>

  </body>
</html>

मैप बनाना

आपने पहले चरण में, जगहों की जानकारी वाली वर्कशीट को सार्वजनिक कर दिया है. इसलिए, उनका मैप बनाने के लिए सर्वर-साइड प्रोग्रामिंग की ज़रूरत नहीं है. दरअसल, इसके लिए प्रोग्रामिंग की ज़रूरत नहीं होती. इस स्प्रेडशीट -> मैप विज़र्ड का इस्तेमाल किया जा सकता है. इससे मैप के लिए ज़रूरी सभी कोड जनरेट हो जाएंगे. विज़र्ड, वर्कशीट की एंट्री को पेज में डाउनलोड करता है. इसके लिए, वह एक स्क्रिप्ट टैग जोड़ता है. यह टैग, फ़ीड के JSON आउटपुट की ओर इशारा करता है. साथ ही, यह एक कॉलबैक फ़ंक्शन तय करता है, जिसे JSON डाउनलोड होने के बाद कॉल किया जाता है. ज़्यादा जानकारी के लिए यहां जाएं.

इसके लिए, एचटीएमएल कोड का सैंपल यहां उपलब्ध है: mainmap.htm. यहां एक स्क्रीनशॉट दिखाया गया है:

नतीजा

हमें उम्मीद है कि अब आपके सर्वर पर, उपयोगकर्ता के योगदान वाला मैप सिस्टम चल रहा होगा. इस लेख में, इस सिस्टम के ज़रूरी पहलुओं के लिए बुनियादी कोड दिया गया है. हालांकि, अब जब आपको Zend Spreadsheets लाइब्रेरी के बारे में पता चल गया है, तो आपको अपनी खास ज़रूरतों के हिसाब से सिस्टम को बेहतर बनाने में कोई परेशानी नहीं होगी. अगर आपको कोई गड़बड़ी मिलती है, तो याद रखें कि डीबग करने के लिए, PHP में echo कमांड या JavaScript में Map API के GLog.write() का इस्तेमाल किया जा सकता है. साथ ही, ज़्यादा मदद पाने के लिए, Maps API या Spreadsheets API डेवलपर फ़ोरम में पोस्ट की जा सकती है.