function handle_request()
 {
     $json = new Services_JSON();
     try {
         global $_PA, $HTTP_RAW_POST_DATA;
         if (!@$_PA->enable_widgetization_server) {
             $this->fail("Widget server is not enabled; you must set \$_PA->enable_widgetization_server = TRUE in local_config.php.");
         }
         if ($_SERVER['REQUEST_METHOD'] != 'POST') {
             $this->fail("This URL handles POST requests only");
         }
         if ($_SERVER['CONTENT_TYPE'] != 'application/x-javascript') {
             $this->fail("Content-Type of application/x-javascript required");
         }
         // Parse input
         $request = $json->decode($HTTP_RAW_POST_DATA);
         if ($request == NULL) {
             $this->fail("Null request");
         }
         if (@$_PA->log_widget_requests) {
             Logger::log("WidgetServer::handle_request(): request={$HTTP_RAW_POST_DATA}", LOGGER_ACTION);
         }
         $this->global = $request->global;
         // This should probably be in config.inc.  For the moment
         // we figure out the network based on the URL, as with the
         // rest of the system.
         PA::$network_info = get_network_info();
         $lang = "english";
         if (!empty($this->global->language)) {
             switch ($this->global->language) {
                 case 'en':
                     break;
                 case 'fr':
                     $lang = "french";
                     break;
                 default:
                     $this->fail("Unknown language: {$this->global}->language");
             }
         }
         PA::load_language($lang);
         // Create items as required
         if (!empty($this->global->items)) {
             foreach ($this->global->items as $item) {
                 $item_params = array();
                 foreach ($item as $k => $v) {
                     $item_params[$k] = $v;
                 }
                 Item::sync($item_params);
                 // create or update row in 'items' database table
             }
         }
         // Set up globals - network, user etc
         if (!empty($this->global->user)) {
             $user_info = array("user_id" => $this->global->user->id, "login_name" => $this->global->user->login, "email" => $this->global->user->email, "first_name" => $this->global->user->first_name, "last_name" => $this->global->user->last_name, "url" => $this->global->user->url, "thumbnail_url" => $this->global->user->thumbnail_url);
             // load (and sync!) or create a shadow user for the current remote user
             PA::$login_user = new ShadowUser($this->global->user->namespace);
             if (!PA::$login_user->load($user_info)) {
                 // we haven't seen this remote user before - create account
                 PA::$login_user = ShadowUser::create($this->global->user->namespace, $user_info, PA::$network_info);
                 //FIXME: need to define what remote urls mean.  in this case "url" should be used instead of /users/$login_name when generating internal urls, so it should go in a global profile block rather than something specific to the remote site.
                 PA::$login_user->set_profile_field($this->global->user->namespace, "url", $this->global->user->url);
             }
             PA::$login_uid = PA::$login_user->user_id;
         }
         // Render modules
         $modules = array();
         foreach ($request->modules as $req_module) {
             $module = array();
             $module['id'] = $req_module->id;
             $module['name'] = $name = $req_module->name;
             $params = array();
             foreach ($req_module->params as $k => $v) {
                 $params[$k] = $v;
             }
             // clean up URLs that may have the port 80 specified
             // this would lead to cross server AJAX problems in safari etc
             // although we are actually on the same server
             // domain.tld:80/file/ and domain.tld/file/
             foreach (array('get_url', 'ajax_url', 'post_url') as $i => $url) {
                 $req_module->{$url} = preg_replace('|:80/*|', '/', $req_module->{$url});
             }
             // dispatch module
             ob_start();
             $module['html'] = $this->render_module($req_module->method, $req_module->name, $req_module->args, $params, $req_module->get_url, $req_module->ajax_url, $req_module->post_url, $req_module->param_prefix);
             // prefix for input parameters and textareas
             $errors = ob_get_contents();
             ob_end_clean();
             if (!empty($errors)) {
                 $module['errors'] = $errors;
             }
             $modules[] = $module;
         }
         $response = array('modules' => $modules);
         header("Content-Type: application/x-javascript");
         echo $json->encode($response);
     } catch (WidgetException $e) {
         echo $json->encode(array("error" => $e->getMessage()));
     }
 }
 function render()
 {
     $login_uid = @PA::$login_user->user_id;
     $this->gid = @$this->params['blog_id'];
     $this->blog_name = @$this->params['blog_name'];
     $this->note = '';
     if ($this->blog_name) {
         $this->find_or_create_blog();
     }
     if ($this->gid) {
         $this->type == 'group';
         $group = new Group();
         $group->collection_id = $this->gid;
         $group->load($this->gid);
         $this->group_member = Group::member_exists($group->collection_id, $login_uid) ? TRUE : FALSE;
         switch ($this->view) {
             case "recent_post":
                 // load content
                 $this->contents = $group->get_contents_for_collection($type = 'all', $cnt = FALSE, 1, 1, 'created', 'DESC');
                 $this->inner_template = 'recent_post.tpl';
                 break;
             case 'user':
                 // load content
                 if (@$this->params['cid']) {
                     // permalink, load only this one
                     $bp = new BlogPost();
                     try {
                         $bp->load((int) $this->params['cid']);
                         $this->count = 1;
                         $content = array();
                         foreach ($bp as $k => $v) {
                             $content[$k] = $v;
                         }
                         $this->contents[] = $content;
                     } catch (PAException $e) {
                         $this->err = __("Couldn't load BlogPost. ") . $e->getMessage();
                     }
                 } else {
                     $this->count = $group->get_contents_for_collection($type = 'all', $cnt = TRUE, 'all', 0, $sort_by = 'created', $direction = 'DESC');
                     $this->contents = $group->get_contents_for_collection($type = 'all', $cnt = FALSE, $this->show, $this->page, 'created', 'DESC');
                 }
                 break;
             case "admin":
                 $this->title = "Managing authors for " . $this->blog_name;
                 $this->inner_template = 'manageauthors.tpl';
                 // find members
                 $this->members = $group->get_members();
                 $this->member_count = count($this->members);
                 break;
         }
         // load Items for all BlogPosts -> for Comments to work
         foreach ($this->contents as $i => $post) {
             $item_params = array("type" => 'blogpost', "id" => $post['content_id'], "name" => $post['content_id'], "thumbnail" => "", "thumbnail_w" => "0", "thumbnail_h" => "0", "genres" => "blog", "url" => $this->blog_url . "?b_cid=" . $post['content_id']);
             Item::sync($item_params);
             // create or update row in 'items' database table
             $item = Item::find_by_subject('blogpost', $post['content_id']);
             $this->contents[$i]['comment_count'] = $item->comment_count;
         }
     } else {
         $this->err = __("No Blog found.");
     }
     $tmp_file = dirname(__FILE__) . "/" . $this->skin . "_" . $this->inner_template;
     $inner_html_gen =& new Template($tmp_file, $this);
     $this->inner_HTML = $inner_html_gen->fetch();
     $content = parent::render();
     return $content;
 }