Skip to content

Commit

Permalink
refs #7893 added possibility to measure mobile apps
Browse files Browse the repository at this point in the history
  • Loading branch information
tsteur committed Jun 17, 2015
1 parent 1f707dd commit 1850138
Show file tree
Hide file tree
Showing 54 changed files with 1,773 additions and 197 deletions.
1 change: 1 addition & 0 deletions config/global.ini.php
Expand Up @@ -718,6 +718,7 @@
Plugins[] = CorePluginsAdmin
Plugins[] = CoreAdminHome
Plugins[] = CoreHome
Plugins[] = WebsiteMeasurable
Plugins[] = Diagnostics
Plugins[] = CoreVisualizations
Plugins[] = Proxy
Expand Down
34 changes: 34 additions & 0 deletions core/Application/Kernel/PluginList.php
Expand Up @@ -25,6 +25,27 @@ class PluginList
*/
private $settings;

/**
* Plugins bundled with core package, disabled by default
* @var array
*/
private $corePluginsDisabledByDefault = array(
'DBStats',
'ExampleCommand',
'ExampleSettingsPlugin',
'ExampleUI',
'ExampleVisualization',
'ExamplePluginTemplate',
'ExampleTracker',
'ExampleReport',
'MobileAppMeasurable'
);

// Themes bundled with core package, disabled by default
private $coreThemesDisabledByDefault = array(
'ExampleTheme'
);

public function __construct(GlobalSettingsProvider $settings)
{
$this->settings = $settings;
Expand Down Expand Up @@ -55,6 +76,16 @@ public function getPluginsBundledWithPiwik()
return $section['Plugins'];
}

/**
* Returns the plugins bundled with core package that are disabled by default.
*
* @return string[]
*/
public function getCorePluginsDisabledByDefault()
{
return array_merge($this->corePluginsDisabledByDefault, $this->coreThemesDisabledByDefault);
}

/**
* Sorts an array of plugins in the order they should be loaded.
*
Expand All @@ -68,6 +99,9 @@ public function sortPlugins(array $plugins)
return $plugins;
}

// we need to make sure a possibly disabled plugin will be still loaded before any 3rd party plugin
$global = array_merge($global, $this->corePluginsDisabledByDefault);

$global = array_values($global);
$plugins = array_values($plugins);

Expand Down
8 changes: 8 additions & 0 deletions core/Db/Schema/Mysql.php
Expand Up @@ -102,6 +102,14 @@ public function getTablesCreateSql()
) ENGINE=$engine DEFAULT CHARSET=utf8
",

'site_setting' => "CREATE TABLE {$prefixTables}site_setting (
idsite INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`setting_name` VARCHAR(255) NOT NULL,
`setting_value` LONGTEXT NOT NULL,
PRIMARY KEY(idsite, setting_name)
) ENGINE=$engine DEFAULT CHARSET=utf8
",

'site_url' => "CREATE TABLE {$prefixTables}site_url (
idsite INTEGER(10) UNSIGNED NOT NULL,
url VARCHAR(255) NOT NULL,
Expand Down
32 changes: 32 additions & 0 deletions core/Measurable/Measurable.php
@@ -0,0 +1,32 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/

namespace Piwik\Measurable;

use Exception;
use Piwik\Site;

/**
* Provides access to individual measurables.
*/
class Measurable extends Site
{

public function getSettingValue($name)
{
$settings = new MeasurableSettings($this->id, $this->getType());
$setting = $settings->getSetting($name);

if (!empty($setting)) {
return $setting->getValue(); // Calling `getValue` makes sure we respect read permission of this setting
}

throw new Exception(sprintf('Setting %s does not exist', $name));
}
}
70 changes: 70 additions & 0 deletions core/Measurable/MeasurableSetting.php
@@ -0,0 +1,70 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/

namespace Piwik\Measurable;

use Piwik\Piwik;

/**
* Describes a Type setting for a website, mobile app, ...
*
* See {@link \Piwik\Plugin\Settings}.
*/
class MeasurableSetting extends \Piwik\Settings\Setting
{
/**
* By default the value of the type setting is only readable by users having at least view access to one site
*
* @var bool
* @since 2.14.0
*/
public $readableByCurrentUser = false;

/**
* By default the value of the type setting is only writable by users having at least admin access to one site
* @var bool
* @internal
*/
public $writableByCurrentUser = false;

/**
* Constructor.
*
* @param string $name The persisted name of the setting.
* @param string $title The display name of the setting.
*/
public function __construct($name, $title)
{
parent::__construct($name, $title);

$this->writableByCurrentUser = Piwik::isUserHasSomeAdminAccess();
$this->readableByCurrentUser = Piwik::isUserHasSomeViewAccess();
}

/**
* Returns `true` if this setting is writable for the current user, `false` if otherwise. In case it returns
* writable for the current user it will be visible in the Plugin settings UI.
*
* @return bool
*/
public function isWritableByCurrentUser()
{
return $this->writableByCurrentUser;
}

/**
* Returns `true` if this setting can be displayed for the current user, `false` if otherwise.
*
* @return bool
*/
public function isReadableByCurrentUser()
{
return $this->readableByCurrentUser;
}
}
103 changes: 103 additions & 0 deletions core/Measurable/MeasurableSettings.php
@@ -0,0 +1,103 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Measurable;

use Piwik\Db;
use Piwik\Piwik;
use Piwik\Plugin\Settings;
use Piwik\Measurable\Settings\Storage;
use Piwik\Settings\Setting;
use Piwik\Measurable\Type;

class MeasurableSettings extends Settings
{

/**
* @var int
*/
private $idSite = null;

/**
* @var string
*/
private $idType = null;

/**
* @param int $idSite The id of a site. If you want to get settings for a not yet created site just pass an empty value ("0")
* @param string $idType If no typeId is given, the type of the site will be used.
*
* @throws \Exception
*/
public function __construct($idSite, $idType)
{
$this->idSite = $idSite;
$this->idType = $idType;
$this->storage = new Storage(Db::get(), $this->idSite);
$this->pluginName = 'MeasurableSettings';

$this->init();
}

protected function init()
{
$typeManager = new Type\Manager();
$type = $typeManager->getType($this->idType);
$type->configureMeasurableSettings($this);

/**
* This event is posted when generating settings for a Measurable (website). You can add any Measurable settings
* that you wish to be shown in the Measurable manager (websites manager). If you need to add settings only for
* eg MobileApp measurables you can use eg `$type->getId() === Piwik\Plugins\MobileAppMeasurable\Type::ID` and
* add only settings if the condition is true.
*
* @since Piwik 2.14.0
* @deprecated will be removed in Piwik 3.0.0
*
* @param MeasurableSettings $this
* @param \Piwik\Measurable\Type $type
* @param int $idSite
*/
Piwik::postEvent('Measurable.initMeasurableSettings', array($this, $type, $this->idSite));
}

public function addSetting(Setting $setting)
{
if ($this->idSite && $setting instanceof MeasurableSetting) {
$setting->writableByCurrentUser = Piwik::isUserHasAdminAccess($this->idSite);
}

parent::addSetting($setting);
}

public function save()
{
Piwik::checkUserHasAdminAccess($this->idSite);

$typeManager = new Type\Manager();
$type = $typeManager->getType($this->idType);

/**
* Triggered just before Measurable settings are about to be saved. You can use this event for example
* to validate not only one setting but multiple ssetting. For example whether username
* and password matches.
*
* @since Piwik 2.14.0
* @deprecated will be removed in Piwik 3.0.0
*
* @param MeasurableSettings $this
* @param \Piwik\Measurable\Type $type
* @param int $idSite
*/
Piwik::postEvent('Measurable.beforeSaveSettings', array($this, $type, $this->idSite));

$this->storage->save();
}

}

104 changes: 104 additions & 0 deletions core/Measurable/Settings/Storage.php
@@ -0,0 +1,104 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/

namespace Piwik\Measurable\Settings;

use Piwik\Db;
use Piwik\Common;
use Piwik\Settings\Setting;

/**
* Storage for site settings
*/
class Storage extends \Piwik\Settings\Storage
{
private $idSite = null;

/**
* @var Db
*/
private $db = null;

private $toBeDeleted = array();

public function __construct(Db\AdapterInterface $db, $idSite)
{
$this->db = $db;
$this->idSite = $idSite;
}

protected function deleteSettingsFromStorage()
{
$table = $this->getTableName();
$sql = "DELETE FROM $table WHERE `idsite` = ?";
$bind = array($this->idSite);

$this->db->query($sql, $bind);
}

public function deleteValue(Setting $setting)
{
$this->toBeDeleted[$setting->getName()] = true;
parent::deleteValue($setting);
}

public function setValue(Setting $setting, $value)
{
$this->toBeDeleted[$setting->getName()] = false; // prevent from deleting this setting, we will create/update it
parent::setValue($setting, $value);
}

/**
* Saves (persists) the current setting values in the database.
*/
public function save()
{
$table = $this->getTableName();

foreach ($this->toBeDeleted as $name => $delete) {
if ($delete) {
$sql = "DELETE FROM $table WHERE `idsite` = ? and `setting_name` = ?";
$bind = array($this->idSite, $name);

$this->db->query($sql, $bind);
}
}

$this->toBeDeleted = array();

foreach ($this->settingsValues as $name => $value) {
$value = serialize($value);

$sql = "INSERT INTO $table (`idsite`, `setting_name`, `setting_value`) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE `setting_value` = ?";
$bind = array($this->idSite, $name, $value, $value);

$this->db->query($sql, $bind);
}
}

protected function loadSettings()
{
$sql = "SELECT `setting_name`, `setting_value` FROM " . $this->getTableName() . " WHERE idsite = ?";
$bind = array($this->idSite);

$settings =$this->db->fetchAll($sql, $bind);

$flat = array();
foreach ($settings as $setting) {
$flat[$setting['setting_name']] = unserialize($setting['setting_value']);
}

return $flat;
}

private function getTableName()
{
return Common::prefixTable('site_setting');
}
}

0 comments on commit 1850138

Please sign in to comment.