initial commit
initial commit

file:b/.gitignore (new)
--- /dev/null
+++ b/.gitignore
@@ -1,1 +1,9 @@
+/theme/tpl_c/*.php
+/vendor
+/upload/*
+/app/Config/app.php
+composer.lock
+/bower_components
+Thumbs.db
+thumbs.db
 

file:b/.htaccess (new)
--- /dev/null
+++ b/.htaccess
@@ -1,1 +1,7 @@
+<IfModule mod_rewrite.c>
+    RewriteEngine On
+    RewriteCond %{REQUEST_FILENAME} !-f
+    RewriteBase /
+    RewriteRule ^ index.php [L,QSA]
+</IfModule>
 

--- /dev/null
+++ b/app/Config/app.sample.php
@@ -1,1 +1,139 @@
+<?php
+return [
+	'App' => [
+        'version' => '0.1',
+		'namespace' => 'App',
+		'encoding' => 'UTF-8',
+		'base' => false,
+		'wwwRoot' => "",
+		'baseUrl' => $_SERVER['SCRIPT_NAME'],
+		'fullBaseUrl' => false,
+		'imageBaseUrl' => 'theme/img/',
+		'cssBaseUrl' => 'theme/css/',
+		'jsBaseUrl' => 'theme/js/'
+	],
 
+	'Environment' => [
+		'example_ro'	=>	"default",
+		'dev_example_ro' => 'development'
+	],
+
+	'Facebook' => [
+		'default' => [
+			'app_id' => '123',
+			'app_secret' => '123',
+			'namespace' => ''
+		],
+		'development' => [
+			'app_id' => '123',
+			'app_secret' => '123',
+			'namespace' => ''
+		],
+	],
+
+	'allowedUploadExtensions' => [
+		'photos'	=>	['jpg', 'jpeg', 'png', 'gif'],
+		'files'	=>	['pdf', 'txt', 'doc', 'docx', 'xls', 'zip', 'rar', 'mp3', 'log', 'odt', 'xlsx']
+	],
+
+	/**
+	 * Security and encryption configuration
+	 *
+	 * - salt - A random string used in security hashing methods.
+	 *   The salt value is also used as the encryption key.
+	 *   You should treat it as extremely sensitive data.
+	 */
+	'Security' => [
+		'salt' => '7b3d3014a731c59dcfc8eccb1574821fc9ddf2e53e4ce9300ba77c0b40c2f5b4',
+	],
+
+	/**
+	 * Apply timestamps with the last modified time to static assets (js, css, images).
+	 * Will append a querystring parameter containing the time the file was modified.
+	 * This is useful for busting browser caches.
+	 *
+	 * Set to true to apply timestamps when debug is true. Set to 'force' to always
+	 * enable timestamping regardless of debug value.
+	 */
+	'Asset' => [
+		// 'timestamp' => true,
+	],
+
+
+	/**
+	 * Email configuration.
+	 *
+	 * You can configure email transports and email delivery profiles here.
+	 *
+	 * By defining transports separately from delivery profiles you can easily
+	 * re-use transport configuration across multiple profiles.
+	 *
+	 * You can specify multiple configurations for production, development and
+	 * testing.
+	 *
+	 * ### Configuring transports
+	 *
+	 * Each transport needs a `className`. Valid options are as follows:
+	 *
+	 *  Mail   - Send using PHP mail function
+	 *  Smtp   - Send using SMTP
+	 *  Debug  - Do not send the email, just return the result
+	 *
+	 * You can add custom transports (or override existing transports) by adding the
+	 * appropriate file to src/Network/Email.  Transports should be named
+	 * 'YourTransport.php', where 'Your' is the name of the transport.
+	 *
+	 * ### Configuring delivery profiles
+	 *
+	 * Delivery profiles allow you to predefine various properties about email
+	 * messages from your application and give the settings a name. This saves
+	 * duplication across your application and makes maintenance and development
+	 * easier. Each profile accepts a number of keys. See `Cake\Network\Email\Email`
+	 * for more information.
+	 */
+	'EmailTransport' => [
+		'default' => [
+			'host' => 'localhost',
+			'port' => 25,
+			'timeout' => 30,
+			//'username' => 'user',
+			//'password' => 'secret',
+			'client' => null,
+			'tls' => null
+		],
+	],
+
+	'Email' => [
+		'default' => [
+			'transport' => 'default',
+			'from' => 'you@localhost',
+			//'charset' => 'utf-8',
+			//'headerCharset' => 'utf-8',
+		],
+	],
+	'Datasources' => [
+		'default' => [
+			'persistent' => false,
+			'host' => 'localhost',
+			//'port' => 'nonstandard_port_number',
+			'username' => '',
+			'password' => '',
+			'database' => '',
+			'encoding' => 'utf8',
+			'timezone' => 'UTC',
+			'cacheMetadata' => true
+		],
+		'development' => [
+			'persistent' => false,
+			'host' => 'localhost',
+			//'port' => 'nonstandard_port_number',
+            'username' => '',
+            'password' => '',
+            'database' => '',
+			'encoding' => 'utf8',
+			'timezone' => 'UTC',
+			'cacheMetadata' => true
+		],
+	],
+];
+

--- /dev/null
+++ b/app/Config/bootstrap.php
@@ -1,1 +1,130 @@
+<?php
 
+use Cake\Core\Configure\Engine\PhpConfig;
+use razvanstanga\fbapp\Lib\Core\Configure;
+use razvanstanga\fbapp\Lib\Database\mySQL;
+use razvanstanga\fbapp\Lib\Network\Request;
+
+require __DIR__ . '/paths.php';
+require APP . "Lib/autoload.php";
+require ROOT . "vendor/autoload.php";
+
+/**
+ * Read configuration file and inject configuration into various
+ * CakePHP classes.
+ *
+ * By default there is only one configuration file. It is often a good
+ * idea to create multiple configuration files, and separate the configuration
+ * that changes from configuration that does not. This makes deployment simpler.
+ */
+try {
+    Configure::config('default', new PhpConfig());
+    Configure::load('app', 'default', false);
+    $environment = Configure::getEnvironment();
+} catch (\Exception $e) {
+    die($e->getMessage() . "\n");
+}
+
+/**
+ * Configure the mbstring extension to use the correct encoding.
+ */
+mb_internal_encoding(Configure::read('App.encoding'));
+
+/**
+ * Smarty
+ */
+$smarty = new Smarty();
+$smarty->compile_check = true;
+$smarty->debugging = false;
+$smarty->template_dir = THEME . "tpl";
+$smarty->compile_dir = THEME . "tpl_c";
+
+$base = Request::getWebroot();
+Configure::write('App.webroot', $base[1]);
+Configure::write('App.facebook', Configure::getFacebookAppConfig());
+
+/**
+ * Set the full base URL.
+ * This URL is used as the base of all absolute links.
+ *
+ * If you define fullBaseUrl in your config file you can remove this.
+ */
+if (!Configure::read('App.fullBaseUrl')) {
+    $s = null;
+    if ($_SERVER['HTTPS']) {
+        $s = 's';
+    }
+
+    $httpHost = $_SERVER['HTTP_HOST'];
+    if (isset($httpHost)) {
+        Configure::write('App.fullBaseUrl', 'http' . $s . '://' . $httpHost);
+    }
+    Configure::write('App.protocol', 'http' . $s . '://');
+    Configure::write('App.domain', $httpHost);
+    unset($httpHost, $s);
+}
+
+/**
+ * Database
+ */
+$DB = mySQL::getInstance("default", Configure::getDatabaseConfig());
+$DB->connectDB();
+
+/**
+ * Facebook
+ */
+$fb = new Facebook\Facebook([
+    'app_id' => Configure::getFacebookAppConfig()['app_id'],
+    'app_secret' => Configure::getFacebookAppConfig()['app_secret'],
+    'default_graph_version' => 'v2.4',
+    'persistent_data_handler' => 'session'
+]);
+
+$helper = $fb->getJavaScriptHelper();
+$sr = $helper->getSignedRequest();
+$user = $sr ? $sr->getUserId() : null;
+
+$accessToken = null;
+try {
+    $accessToken = $helper->getAccessToken();
+} catch(Facebook\Exceptions\FacebookResponseException $e) {
+    // When Graph returns an error
+    //echo 'Graph returned an error: ' . $e->getMessage();
+    //exit;
+} catch(Facebook\Exceptions\FacebookSDKException $e) {
+    // When validation fails or other local issues
+    //echo 'Facebook SDK returned an error: ' . $e->getMessage();
+    //exit;
+}
+if (!isset($accessToken) || $accessToken == null) {
+    $helper = $fb->getCanvasHelper();
+    try {
+        $accessToken = $helper->getAccessToken();
+    } catch(Facebook\Exceptions\FacebookResponseException $e) {
+        // When Graph returns an error
+        //echo 'Graph returned an error: ' . $e->getMessage();
+        //exit;
+    } catch(Facebook\Exceptions\FacebookSDKException $e) {
+        // When validation fails or other local issues
+        //echo 'Facebook SDK returned an error: ' . $e->getMessage();
+        //exit;
+    }
+}
+
+if ($accessToken != null) {
+    $_SESSION['FBAPP_access_token'] = $accessToken->getValue();
+}
+$fb->setDefaultAccessToken((string) $_SESSION['FBAPP_access_token']);
+
+if (isset($user) && $user != null) {
+    Configure::write('App.user_id', $user);
+    Configure::write('App.logged_in', true);
+} else {
+    Configure::write('App.logged_in', false);
+}
+
+/**
+ * Assign APP to smarty
+ */
+$smarty->assign("APP", Configure::read('App'));
+

--- /dev/null
+++ b/app/Config/paths.php
@@ -1,1 +1,25 @@
+<?php
 
+if (!defined('DS')) {
+    define('DS', DIRECTORY_SEPARATOR);
+}
+
+/**
+ * The full path to the directory which holds "app", WITHOUT a trailing DS.
+ */
+define('ROOT', dirname(dirname(__DIR__)) . DS);
+
+/**
+ * Path to the theme directory
+ */
+define('THEME', ROOT . 'theme' . DS);
+
+/**
+ * App dir
+ */
+define('APP', dirname(__DIR__) . DS);
+
+/**
+ * Config dir
+ */
+define('CONFIG', __DIR__ . DS);

--- /dev/null
+++ b/app/Controller/AppController.php
@@ -1,1 +1,61 @@
+<?php
 
+namespace razvanstanga\fbapp\Controller;
+
+use razvanstanga\fbapp\Lib\Network\Request;
+
+class AppController {
+    public $DB;
+    public $smarty;
+    public $fb;
+    public $fb_id;
+
+    public function __construct()
+    {
+    }
+
+    public function DB($instance)
+    {
+        $this->DB = $instance;
+    }
+
+    public function smarty($instance)
+    {
+        $this->smarty = $instance;
+    }
+
+    public function facebook($instance)
+    {
+        $this->fb = $instance;
+        $helper = $this->fb->getJavaScriptHelper();
+        $sr = $helper->getSignedRequest();
+        $this->fb_id = $sr ? $sr->getUserId() : null;
+
+        $this->registerUser();
+    }
+
+    protected function registerUser()
+    {
+        try {
+            $res = $this->fb->get('/me?fields=first_name,last_name,email,gender,hometown');
+            $profile = $res->getGraphObject();
+            $uD = [];
+            $uD['first_name'] = $this->DB->real_escape_string($profile->getProperty('first_name'));
+            $uD['last_name'] = $this->DB->real_escape_string($profile->getProperty('last_name'));
+            $uD['email'] = $this->DB->real_escape_string($profile->getProperty('email'));
+            $uD['gender'] = $this->DB->real_escape_string($profile->getProperty('gender'));
+            $uD['hometown'] = $this->DB->real_escape_string($profile->getProperty('hometown'));
+            $this->DB->query("SELECT `id` FROM `users` WHERE `fb_id`='".$this->fb_id."'");
+            $row = $this->DB->fetch_array();
+            if ($row['id']) {
+                $this->DB->query("UPDATE `users` SET `first_name`='".$uD['first_name']."', `last_name`='".$uD['last_name']."', `email`='".$uD['email']."', `gender`='".$uD['gender']."', `hometown`='".$uD['hometown']."' WHERE `fb_id`='".$this->fb_id."'");
+            } else {
+                $row = $this->DB->query("INSERT INTO `users` (`id`, `fb_id`, `first_name`, `last_name`, `email`, `gender`, `hometown`, `date`, `ip`, `active`) VALUES
+                    (NULL, '".$this->fb_id."', '".$uD['first_name']."', '".$uD['last_name']."', '".$uD['email']."', '".$uD['gender']."', '".$uD['hometown']."', '".date("Y-m-d H:i:s")."', '".Request::clientIp()."', 1);");
+            }
+        } catch (\Exception $e) {
+            //die($e->getMessage() . "\n");
+        }
+    }
+}
+

--- /dev/null
+++ b/app/Controller/DefaultController.php
@@ -1,1 +1,21 @@
+<?php
 
+namespace razvanstanga\fbapp\Controller;
+
+use razvanstanga\fbapp\Controller\AppController;
+use razvanstanga\fbapp\Lib\Network\Request;
+
+class DefaultController extends AppController {
+    public function index()
+    {
+        $this->smarty->assign("page", "default/index");
+        $this->smarty->display("layout/index.tpl");
+    }
+
+    public function test()
+    {
+        $this->smarty->assign("page", "default/test");
+        $this->smarty->display("layout/index.tpl");
+    }
+}
+

--- /dev/null
+++ b/app/Lib/Core/Configure.php
@@ -1,1 +1,35 @@
+<?php
 
+namespace razvanstanga\fbapp\Lib\Core;
+
+use Cake\Core\Configure as CakeConfigure;
+
+class Configure extends CakeConfigure {
+    protected static $environment;
+
+    public static function getEnvironment()
+    {
+        static::$environment = static::read("Environment.".str_replace(".", "_", $_SERVER['HTTP_HOST']));
+        return static::$environment;
+    }
+
+    public static function getFacebookAppConfig()
+    {
+        $data = static::read("Facebook." . static::$environment);
+        if (!$data) {
+            throw new \Exception('No facebook app config for environment' . static::$environment);
+        }
+        return $data;
+    }
+
+    public static function getDatabaseConfig()
+    {
+        $data = static::read("Datasources." . static::$environment);
+        if (!$data) {
+            throw new \Exception('No database config for environment' . static::$environment);
+        }
+        return $data;
+    }
+}
+
+?>

--- /dev/null
+++ b/app/Lib/Database/mySQL.php
@@ -1,1 +1,183 @@
+<?php

+

+namespace razvanstanga\fbapp\Lib\Database;

+

+class mySQL {

+    public static $obj = [];

+    public $adminmail;

+    private $query_id;

+    private $db;

+    private $query_count;

+    private $query_time;

+    private $error;

+    private $errno;

+    private $sqlstate;

+    private $reporterror;

+    private $record_row;

+    public $debug;

+    public static $instance;

+

+    public static function getInstance ($id="default", array $obj = [])

+    {

+        if (self::$instance[$id] == null) {

+            self::$instance[$id] = new self;

+        }

+        static::$obj = array_merge(static::$obj, $obj);

+        return static::$instance[$id];

+    }

+

+    public function __construct()

+    {

+        $this->obj = [

+            "database" => "",

+            "username" => "",

+            "password" => "",

+            "host" => "localhost",

+            "port" => 3306,

+            "persistent" => 0,

+            "encoding" => "utf8",

+            "cached_queries" => [],

+        ];

+        $this->adminmail        = "";

+        $this->query_id         = "";

+        $this->db               = "";

+        $this->query_count      = 0;

+        $this->query_time       = 0;

+        $this->error            = "";

+        $this->errno            = 0;

+        $this->reporterror      = 1;

+        $this->record_row       = [];

+        $this->debug            = 0;

+    }

+

+    public function connectDB()

+    {

+        mysqli_report(MYSQLI_REPORT_STRICT);

+        try  {

+            $this->db = new \mysqli(static::$obj['host'], static::$obj['username'], static::$obj['password'], static::$obj['database'], static::$obj['port']);

+        } catch (\Exception $e) {

+            throw new \Exception('There is a problem connecting to the database. The error is : ' . $e->getMessage());

+        }

+

+        $this->db->set_charset($this->obj['encoding']);

+    }

+

+    public function query($the_query, $debug=0)

+    {

+        $query_time_start = $this->getmicrotime();

+        $this->query_id = $this->db->query($the_query);

+        $query_time_end = $this->getmicrotime();

+

+        $this->query_time = $this->query_time + ($query_time_end - $query_time_start);

+

+        if (!$this->query_id) {

+            throw new \Exception("Database query error : ". $the_query);

+        }

+        if ($debug || $this->debug) {

+            echo $the_query."\r\n";

+        }

+        $this->query_count++;

+        $this->obj['cached_queries'][] = $the_query;

+        return $this->query_id;

+    }

+

+    public function geterror()

+    {

+        $this->error = $this->db->error;

+        return $this->error;

+    }

+

+    public function getsqlstate()

+    {

+        $this->sqlstate = $this->db->sqlstate;

+        return $this->sqlstate;

+    }

+

+    public function getprettyerror()

+    {

+        $error = $this->error;

+        if (eregi("duplicate", $this->error)) {

+            $error = "Duplicate value\r\n";

+            $error .= $this->error;

+        }

+        return $error;

+    }

+

+    public function geterrno()

+    {

+        $this->errno = $this->db->errno;

+        return $this->errno;

+    }

+

+    public function fetch_array($query_id="")

+    {

+        if ($query_id == "") {

+            $query_id = $this->query_id;

+        }

+        if ($query_id) {

+            $this->record_row = $query_id->fetch_array(MYSQLI_ASSOC);

+            return $this->record_row;

+        } else {

+            exit ();

+        }

+    }

+

+    public function fetch_row($query_id="")

+    {

+        if ($query_id == "") {

+            $query_id = $this->query_id;

+        }

+        $this->record_row = $query_id->fetch_array(MYSQLI_ASSOC);

+        return $this->record_row;

+    }

+

+    public function get_affected_rows()

+    {

+        return $this->db->affected_rows;

+    }

+

+    public function get_num_rows()

+    {

+        return $this->query_id->num_rows;

+    }

+

+    public function get_insert_id()

+    {

+        return $this->db->insert_id;

+    }

+

+    public function get_query_cnt()

+    {

+        return $this->query_count;

+    }

+

+    public function get_query_time()

+    {

+        return $this->query_time;

+    }

+

+    public function free_result($query_id="")

+    {

+        if ($query_id == "") {

+            $query_id = $this->query_id;

+        }

+        @mysql_free_result($query_id);

+    }

+

+    public function real_escape_string($string)

+    {

+        return $this->db->real_escape_string ($string);

+    }

+

+    public function close_db()

+    {

+        return $this->db->close();

+    }

+

+    public function getmicrotime()

+    {

+        list($usec, $sec) = explode(" ",microtime());

+        return ((float)$usec + (float)$sec);

+    }

+}

 

--- /dev/null
+++ b/app/Lib/Network/Request.php
@@ -1,1 +1,109 @@
+<?php
 
+namespace razvanstanga\fbapp\Lib\Network;
+
+class Request {
+    /**
+     * Returns a base URL and sets the proper webroot
+     *
+     * If CakePHP is called with index.php in the URL even though
+     * URL Rewriting is activated (and thus not needed) it swallows
+     * the unnecessary part from $base to prevent issue #3318.
+     *
+     * @return array Base URL, webroot dir ending in /
+     */
+    public static function getWebroot()
+    {
+        $base = $webroot = null;
+        $baseUrl = $_SERVER['SCRIPT_NAME'];
+
+        if ($base !== false && $base !== null) {
+            return [$base, $base . '/'];
+        }
+
+        if (!$baseUrl) {
+            $base = dirname($_SERVER['PHP_SELF']);
+            // Clean up additional / which cause following code to fail..
+            $base = preg_replace('#/+#', '/', $base);
+
+            $indexPos = strpos($base, '/' . $webroot . '/index.php');
+            if ($indexPos !== false) {
+                $base = substr($base, 0, $indexPos) . '/' . $webroot;
+            }
+            if ($webroot === basename($base)) {
+                $base = dirname($base);
+            }
+
+            if ($base === DS || $base === '.') {
+                $base = '';
+            }
+            $base = implode('/', array_map('rawurlencode', explode('/', $base)));
+            return [$base, $base . '/'];
+        }
+
+        $file = '/' . basename($baseUrl);
+        $base = dirname($baseUrl);
+
+        if ($base === DS || $base === '.') {
+            $base = '';
+        }
+        $webrootDir = $base . '/';
+
+        $docRoot = $_SERVER['DOCUMENT_ROOT'];
+        $docRootContainsWebroot = strpos($docRoot, $webroot);
+
+        if (!empty($base) || !$docRootContainsWebroot) {
+            if (strpos($webrootDir, '/' . $webroot . '/') === false) {
+                $webrootDir .= $webroot;
+            }
+        }
+        return [$base . $file, $webrootDir];
+    }
+
+    public static function getCA()
+    {
+        $webRoot = static::getWebroot();
+        $relativeUrl = str_replace($webRoot[1], '', $_SERVER['REQUEST_URI']);
+        $url = explode ("/", $relativeUrl);
+        return ["controller" => static::formatController($url[0]), "action" => static::formatAction($url[1])];
+    }
+
+    private static function formatController($str)
+    {
+        $str = mb_strtolower($str);
+        $str = str_replace("_", " ", $str);
+        $str = ucwords($str);
+        $str = trim($str) ? trim($str) : "Default";
+        return $str;
+    }
+
+    private static function formatAction($str)
+    {
+        $str = mb_strtolower($str);
+        if (strpos($str, '?') !== false) {
+            $str = explode('?', $str);
+            $str = $str[0];
+        }
+        $str = trim($str) ? trim($str) : "index";
+        return $str;
+    }
+
+    /**
+     * Get the IP the client is using, or says they are using.
+     *
+     * @return string The client IP.
+     */
+    public static function clientIp()
+    {
+        if ($_SERVER['HTTP_X_FORWARDED_FOR']) {
+            $ipaddr = preg_replace('/(?:,.*)/', '', $_SERVER['HTTP_X_FORWARDED_FOR']);
+        } else {
+            if ($_SERVER['HTTP_CLIENT_IP']) {
+                $ipaddr = $_SERVER['HTTP_CLIENT_IP'];
+            } else {
+                $ipaddr = $_SERVER['REMOTE_ADDR'];
+            }
+        }
+        return trim($ipaddr);
+    }
+}

--- /dev/null
+++ b/app/Lib/autoload.php
@@ -1,1 +1,36 @@
+<?php
 
+if (version_compare(PHP_VERSION, '5.4.0', '<')) {
+	throw new Exception('app requires PHP version 5.4 or higher.');
+}
+/**
+* Register the autoloader
+*
+* @param string $class The fully-qualified class name.
+* @return void
+*/
+spl_autoload_register(function ($class)
+{
+	// project-specific namespace prefix
+	$prefix = 'razvanstanga\\fbapp\\';
+	// base directory for the namespace prefix
+	$base_dir = ROOT . '/app/';
+	// does the class use the namespace prefix?
+	$len = strlen($prefix);
+	if (strncmp($prefix, $class, $len) !== 0) {
+		// no, move to the next registered autoloader
+		return;
+	}
+	// get the relative class name
+	$relative_class = substr($class, $len);
+	// replace the namespace prefix with the base directory, replace namespace
+	// separators with directory separators in the relative class name, append
+	// with .php
+	$file = $base_dir . str_replace('\\', '/', $relative_class) . '.php';
+
+	// if the file exists, require it
+	if (file_exists($file)) {
+		require $file;
+	}
+});
+

file:b/bower.json (new)
--- /dev/null
+++ b/bower.json
@@ -1,1 +1,22 @@
+{
+  "name": "fbapp demo",
+  "authors": [
+    "Razvan Stanga <git@razvi.ro>"
+  ],
+  "description": "ui components",
+  "main": "",
+  "moduleType": [],
+  "license": "MIT",
+  "homepage": "",
+  "ignore": [
+    "**/.*",
+    "node_modules",
+    "bower_components",
+    "test",
+    "tests"
+  ],
+  "dependencies": {
+    "bootstrap": "~3.3.6"
+  }
+}
 

file:b/composer.json (new)
--- /dev/null
+++ b/composer.json
@@ -1,1 +1,28 @@
+{
+    "name": "fbapp demo",
+    "description": "",
+    "homepage": "http://git.razvi.ro",
+    "type": "project",
+    "license": "MIT",
+    "require": {
+        "php": ">=5.4.16",
+        "smarty/smarty": "^3.1@dev",
+        "facebook/php-sdk-v4": "^5.0@dev",
+        "cakephp/core": "dev-master"
+    },
+    "require-dev": {
+    },
+    "suggest": {
+        "phpunit/phpunit": "Allows automated tests to be run without system-wide install."
+    },
+    "autoload": {
+        "psr-4": {
+            "razvanstanga\\fbapp\\": "app"
+        }
+    },
+    "autoload-dev": {
+    },
+    "minimum-stability": "dev",
+    "prefer-stable": true
+}
 

file:b/index.php (new)
--- /dev/null
+++ b/index.php
@@ -1,1 +1,31 @@
+<?php
 
+Header ("P3P: policyref=\"/w3c/p3p.xml\", CP=\"ALL IND DSP COR ADM CONo CUR IVAo IVDo PSA PSD TAI TELo OUR SAMo CNT COM INT NAV ONL PHY PRE PUR UNI\"");
+session_start();
+require (__DIR__ . "/app/Config/bootstrap.php");
+
+use razvanstanga\fbapp\Lib\Network\Request;
+
+$action = isset($_GET['action']) ? $_GET['action'] : 'index';
+
+switch($action){
+    default;
+        $CA = Request::getCA();
+        $controller = $CA['controller'];
+        $action = $CA['action'];
+        $controllerPath = '\razvanstanga\fbapp\Controller\\'.$controller.'Controller';
+        if (!class_exists($controllerPath)) {
+            $controllerPath = '\razvanstanga\fbapp\Controller\DefaultController';
+        }
+        $controllerInstance = new $controllerPath();
+        $controllerInstance->smarty($smarty);
+        $controllerInstance->DB($DB);
+        $controllerInstance->facebook($fb);
+        if (method_exists ($controllerInstance, $action)) {
+            $controllerInstance->$action();
+        } else {
+            $controllerInstance->index();
+        }
+    break;
+}
+

file:b/setpermissions.sh (new)
--- /dev/null
+++ b/setpermissions.sh
@@ -1,1 +1,32 @@
+#!/bin/sh
 
+if [ -s $1 ]
+then
+    echo "usage : ./setpermissions.sh dev|prod"
+    exit;
+fi
+
+if [ $1 == "dev" ]
+then
+	find . -type f -print0 | xargs -0 chmod 0664
+	find . -type d -print0 | xargs -0 chmod 0775
+
+	chown -R user.group .htaccess
+	chown -R user.group *
+	chown -R apache.apache theme/tpl_c
+
+	chmod 0600 composer.json composer.lock .gitignore
+fi
+
+if [ $1 == "prod" ]
+then
+	find . -type f -print0 | xargs -0 chmod 0644
+	find . -type d -print0 | xargs -0 chmod 0755
+
+	chown -R user.group .htaccess
+	chown -R user.group *
+	chown -R apache.apache theme/tpl_c
+
+	chmod 0600 composer.json composer.lock .gitignore
+fi
+

symlink:b/theme/bower (new)
--- /dev/null
+++ b/theme/bower
@@ -1,1 +1,1 @@
-
+../bower_components

file:b/theme/css/.keep (new)
--- /dev/null
+++ b/theme/css/.keep

--- /dev/null
+++ b/theme/images/.keep

file:b/theme/js/fb.js (new)
--- /dev/null
+++ b/theme/js/fb.js
@@ -1,1 +1,157 @@
+(function(){
+    // If we've already installed the SDK, we're done
+    if (document.getElementById('facebook-jssdk')) {return;}
+    // Get the first script element, which we'll use to find the parent node
+    var firstScriptElement = document.getElementsByTagName('script')[0];
+    // Create a new script element and set its id
+    var facebookJS = document.createElement('script');
+    facebookJS.id = 'facebook-jssdk';
+    // Set the new script's source to the source of the Facebook JS SDK
+    facebookJS.src = '//connect.facebook.net/en_US/all.js';
+    // Insert the Facebook JS SDK into the DOM
+    firstScriptElement.parentNode.insertBefore(facebookJS, firstScriptElement);
+}());
 
+window.fbAsyncInit = function()
+{
+    FB.init({
+        appId       : FBAPP.id,
+        status      : true,
+        cookie      : true,
+        xfbml       : true,
+        version     : 'v2.4'
+    });
+    FB.Canvas.setSize({ width: 800, height: 640 });
+
+    FB.getLoginStatus(function(response) {
+        if ( response.status == "connected" ) {
+        }
+    });
+
+    FB.Event.subscribe('auth.login', function(response) {
+        onFacebookLogin();
+        ga('send', 'event', 'Facebook', 'Logged in', '');
+    });
+
+    FB.Event.subscribe('edge.create', function(response) {
+    });
+};
+
+function postToFeed(obj)
+{
+    FB.ui(obj);
+    ga('send', 'event', 'Facebook', 'Share', '');
+}
+
+function loginButton()
+{
+    ga('send', 'event', 'Facebook', 'Login attempt', '');
+    if( navigator.userAgent.match('CriOS') ) {
+        window.open('https://www.facebook.com/dialog/oauth?client_id='+FBAPP.id+'&redirect_uri='+ document.location.href +'&scope=email,publish_actions', '', null);
+    } else {
+        var location = window.location;
+        FB.getLoginStatus(function(response) {
+            if ( response.status == "connected" ) {
+                //checkPermission();
+            } else {
+                FB.login(function(response) {
+                    if (response.authResponse) {
+                        /*FB.api('/me', function(response) {
+                            setTimeout(function(){
+                                FB.api('/me/permissions', function(response2) {
+                                    if (checkJsonPermission(response2.data, 'publish_actions')) {
+
+                                    } else {
+                                        //showNotifications ([""], 'Facebook');
+                                        ga('send', 'event', 'Facebook', 'Publish actions canceled', '');
+                                    }
+                                });
+                            }, 1000);
+                        });*/
+                    } else {
+                        showNotifications (["Please login"], 'Facebook');
+                        ga('send', 'event', 'Facebook', 'Login canceled', '');
+                    }
+                }, {scope: 'email'});
+            }
+        });
+    }
+}
+
+function checkPermission()
+{
+    FB.api('/me/permissions', function(response) {
+        if ( checkJsonPermission(response.data, 'publish_actions') ){
+        } else {
+            FB.login(function(response1) {
+                setTimeout(function(){
+                    FB.api('/me/permissions', function(response2) {
+                        if (checkJsonPermission(response2.data, 'publish_actions')) {
+                            publishPhoto();
+                        } else {
+                            showNotifications (["We need your approval to proceed"], 'Facebook');
+                            ga('send', 'event', 'Facebook', 'Publish actions canceled', '');
+                        }
+                    });
+                }, 1000);
+            }, {scope: 'email,publish_actions'});
+        }
+    });
+}
+
+function checkJsonPermission(_data, _check)
+{
+    var ret = false;
+    $(_data).each(function (k, v){
+        if (v.permission == _check && v.status == "granted") {
+            ret = true;
+        }
+    });
+    return ret;
+}
+
+function showNotifications(errors, category)
+{
+    $('.errors_placeholder').html('<button type="button" class="close"> &times;</button>');
+    $('.errors_placeholder').addClass('active');
+    $(".errors_placeholder").on("click",".close",function(){
+        $(".errors_placeholder").removeClass('active');
+    })
+    $(errors).each(function (k, v){
+        $('.errors_placeholder').append('<div>'+v+'</div>');
+        ga('send', 'event', 'Errors', category, v);
+    });
+    clearTimeout (timeout);
+    timeout = setTimeout(function(){
+    $('.errors_placeholder').removeClass('active');
+    }, 4000);
+}
+
+
+/**
+* Custom for each app
+*/
+var loginFrom = null;
+function onFacebookLogin()
+{
+    if (loginFrom == 'start') {
+        window.location = FBAPP.path;
+    } else {
+        window.location = FBAPP.path;
+    }
+}
+
+$(document).ready(function(){
+    $('.share-fb').click(function(){
+        var src = $('.img').attr('src');
+        var obj = {
+            method: 'feed',
+            link: '',
+            name: '',
+            caption: '',
+            description: '',
+            picture: src.replace('https', 'http')
+        };
+        postToFeed(obj);
+    });
+});

file:b/theme/js/init.js (new)
--- /dev/null
+++ b/theme/js/init.js
@@ -1,1 +1,22 @@
+$(document).ready(function(){
+    //$.noConflict();
 
+    $.ajaxSetup ({
+        cache: false
+    });
+
+    $(window).bind("scroll", function(){
+        var offset = $(this).scrollTop() + $(document).innerHeight()/2;
+        $('.loader').css ('top', offset);
+    });
+
+    $(document).ajaxStart(function(){
+        var offset = $(window).scrollTop() + $(document).innerHeight()/2;
+        $('.loader').fadeIn(100);
+    });
+
+    $(document).ajaxComplete(function(){
+        $('.loader').hide();
+    });
+});
+

--- /dev/null
+++ b/theme/tpl/content/default/index.tpl
@@ -1,1 +1,7 @@
 
+<div class="main">
+	<div class="container">
+
+	</div>
+</div>
+

--- /dev/null
+++ b/theme/tpl/content/default/test.tpl
@@ -1,1 +1,1 @@
-
+test

--- /dev/null
+++ b/theme/tpl/elements/footer.tpl
@@ -1,1 +1,14 @@
-
+{literal}

+<script type="text/javascript">

+  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){

+  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),

+  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)

+  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

+

+  ga('create', '', 'auto');

+  ga('send', 'pageview');

+

+</script>

+{/literal}

+	</body>

+</html>

--- /dev/null
+++ b/theme/tpl/elements/header.tpl
@@ -1,1 +1,22 @@
-
+<html>

+	<head>

+	<meta charset="utf-8">

+		<title></title>

+		<link rel="stylesheet" href="{$APP.webroot}theme/css/style.css?v{$APP.version}">

+	</head>

+    {literal}

+    <script type="text/javascript">

+    var FBAPP = {

+        id : {/literal}{$APP.facebook.app_id}{literal},

+        namespace : '{/literal}{$APP.facebook.namespace}{literal}',

+        path : '{/literal}{$APP.webroot}{literal}',

+        protocol : '{/literal}{$APP.protocol}{literal}',

+        domain : '{/literal}{$APP.domain}{literal}'

+    }

+    {/literal}

+    </script>

+    <script type="text/javascript" src="{$APP.webroot}theme/bower/jquery/dist/jquery.min.js?v{$APP.version}"></script>

+    <script type="text/javascript" src="{$APP.webroot}theme/bower/bootstrap/dist/js/bootstrap.min.js?v{$APP.version}"></script>

+    <script type="text/javascript" src="{$APP.webroot}theme/js/init.js?v{$APP.version}"></script>

+    <script type="text/javascript" src="{$APP.webroot}theme/js/fb.js?v{$APP.version}"></script>

+	<body>

--- /dev/null
+++ b/theme/tpl/layout/index.tpl
@@ -1,1 +1,9 @@
+{include file="elements/header.tpl"}
 
+{if file_exists("`$smarty.const.THEME`tpl/content/`$page`.tpl")}
+    {include file="content/`$page`.tpl"}
+{else}
+    {include file="content/default/index.tpl"}
+{/if}
+
+{include file="elements/footer.tpl"}

file:b/theme/tpl_c/.keep (new)
--- /dev/null
+++ b/theme/tpl_c/.keep

file:b/w3c/p3p.xml (new)
--- /dev/null
+++ b/w3c/p3p.xml
@@ -1,1 +1,8 @@
-
+<?xml version="1.0" encoding="UTF-8" ?>

+<META xmlns="http://www.w3.org/2001/09/P3Pv1">

+    <POLICY-REFERENCES>

+        <POLICY-REF about="/w3c/policy.xml">

+            <INCLUDE>/*</INCLUDE>

+        </POLICY-REF>

+    </POLICY-REFERENCES>

+</META>

file:b/w3c/policy.xml (new)
--- /dev/null
+++ b/w3c/policy.xml
@@ -1,1 +1,24 @@
+<?xml version="1.0" encoding="UTF-8" ?>

+<POLICY xmlns="http://www.w3.org/2000/12/P3Pv1" discuri="url">

+        <ENTITY>

+                <DATA-GROUP>

+                        <DATA ref="#business.name">name</DATA>

+                        <DATA ref="#business.contact-info.postal.street">street</DATA>

+                        <DATA ref="#business.contact-info.postal.city">city</DATA>

+                        <DATA ref="#business.contact-info.postal.stateprov">n/a</DATA>

+                        <DATA ref="#business.contact-info.postal.country">country</DATA>

+                        <DATA ref="#business.contact-info.postal.postalcode">postalcode</DATA>

+                        <DATA ref="#business.contact-info.online.email">email</DATA>

+                        <DATA ref="#business.contact-info.online.uri">uri</DATA>

+                </DATA-GROUP>

+        </ENTITY>

+        <ACCESS>

+                <all/>

+        </ACCESS>

+        <DISPUTES-GROUP>

+                <DISPUTES resolution-type="service" service="mailto:email" short-description="name customer service">

+                        <LONG-DESCRIPTION>If you have any complaints, please notify us by e-mail at email</LONG-DESCRIPTION>

+                </DISPUTES>

+        </DISPUTES-GROUP>

+</POLICY>

 

comments