From 1f9d0aed08a6a456b28032200bbcbfa72453100e Mon Sep 17 00:00:00 2001 From: Corne Oppelaar Date: Sun, 19 Jun 2016 15:07:42 +0200 Subject: [PATCH 1/7] add web setup script --- bin/setup_web | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100755 bin/setup_web diff --git a/bin/setup_web b/bin/setup_web new file mode 100755 index 0000000..c6d5c05 --- /dev/null +++ b/bin/setup_web @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +cd "$(realpath "$(dirname "$0")/..")"; + +composer install; +mkdir storage; +touch storage/db.sqlite; +./vendor/bin/propel sql:build +./vendor/bin/propel sql:insert; + +echo "Done setting up web environment" + From 530b9de71851e5a23b63d322a6454d96e7aeb2ca Mon Sep 17 00:00:00 2001 From: Corne Oppelaar Date: Sun, 19 Jun 2016 19:48:25 +0200 Subject: [PATCH 2/7] show contributors and add GitHub and Stash service --- composer.json | 3 +- composer.lock | 110 +++++++++++++++++++++++++++++++++++++++- config/app.yml | 9 ++-- public/css/main.css | 19 +++++-- public/css/main.css.map | 2 +- public/css/main.scss | 22 ++++++-- public/index.php | 2 +- public/js/home.js | 17 +++++++ public/js/zerooo.js | 81 +++++++++++++++++++++++++++++ src/Core.php | 1 - src/Handler/Home.php | 23 ++++++++- src/Service/GitHub.php | 85 +++++++++++++++++++++++++++++++ src/Service/Stash.php | 15 ++++++ views/home.html.twig | 16 +++++- 14 files changed, 385 insertions(+), 20 deletions(-) create mode 100644 public/js/home.js create mode 100644 public/js/zerooo.js create mode 100644 src/Service/GitHub.php create mode 100644 src/Service/Stash.php diff --git a/composer.json b/composer.json index 05dded1..0b8f86d 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,8 @@ "hassankhan/config": "0.10.0", "monolog/monolog": "1.18.1", "aura/session": "2.0.1", - "guzzlehttp/guzzle": "^6.2" + "guzzlehttp/guzzle": "^6.2", + "tedivm/stash": "^0.14.1" }, "autoload": { "psr-4": { diff --git a/composer.lock b/composer.lock index d72b704..df8bd21 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "95b6dc2302dd6086dbc2b7248a1f5768", - "content-hash": "61847eefe53610226629206b81b6f8b5", + "hash": "7f7a5098d89b4841741255592bee1890", + "content-hash": "045408fd26a025036d65a2e00bb8a369", "packages": [ { "name": "aura/session", @@ -558,6 +558,52 @@ ], "time": "2015-06-27 11:58:48" }, + { + "name": "psr/cache", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "9e66031f41fbbdda45ee11e93c45d480ccba3eb3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/9e66031f41fbbdda45ee11e93c45d480ccba3eb3", + "reference": "9e66031f41fbbdda45ee11e93c45d480ccba3eb3", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "time": "2015-12-11 02:52:07" + }, { "name": "psr/http-message", "version": "1.0", @@ -1167,6 +1213,66 @@ "homepage": "https://symfony.com", "time": "2016-03-04 07:54:35" }, + { + "name": "tedivm/stash", + "version": "v0.14.1", + "source": { + "type": "git", + "url": "https://github.com/tedious/Stash.git", + "reference": "bcb739b08b22571e35589ebe5403af9b89a33394" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tedious/Stash/zipball/bcb739b08b22571e35589ebe5403af9b89a33394", + "reference": "bcb739b08b22571e35589ebe5403af9b89a33394", + "shasum": "" + }, + "require": { + "php": "^5.4|^7.0", + "psr/cache": "~1.0" + }, + "provide": { + "psr/cache-implementation": "1.0.0" + }, + "require-dev": { + "fabpot/php-cs-fixer": "^1.9", + "phpunit/phpunit": "4.8.*", + "satooshi/php-coveralls": "1.0.*" + }, + "type": "library", + "autoload": { + "psr-4": { + "Stash\\": "src/Stash/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Robert Hafner", + "email": "tedivm@tedivm.com" + }, + { + "name": "Josh Hall-Bachner", + "email": "charlequin@gmail.com" + } + ], + "description": "The place to keep your cache.", + "homepage": "http://github.com/tedious/Stash", + "keywords": [ + "apc", + "cache", + "caching", + "memcached", + "psr-6", + "psr6", + "redis", + "sessions" + ], + "time": "2016-02-10 22:23:16" + }, { "name": "twig/twig", "version": "v1.24.0", diff --git a/config/app.yml b/config/app.yml index 59fe567..47490a7 100644 --- a/config/app.yml +++ b/config/app.yml @@ -3,9 +3,10 @@ core: level: debug debug: true container: - name: "Glim" - author: "Corné Oppelaar " + name: "Zer.ooo" + author: "EaterOfCode" sessionName: '0sess' + github-repo: 'EaterOfCode/zer.ooo' services: slim: Eater\Glim\Service\Slim user: Eater\Glim\Service\User @@ -13,4 +14,6 @@ core: twig: Eater\Glim\Service\Twig twig-vars: Eater\Glim\Service\TwigVars ca: Eater\Glim\Service\CA - server: Eater\Glim\Service\Server \ No newline at end of file + server: Eater\Glim\Service\Server + stash: Eater\Glim\Service\Stash + github: Eater\Glim\Service\GitHub \ No newline at end of file diff --git a/public/css/main.css b/public/css/main.css index e0fc744..2613ca2 100644 --- a/public/css/main.css +++ b/public/css/main.css @@ -151,18 +151,27 @@ body { display: flex; flex-direction: column; justify-content: center; - align-items: center; - height: 20vh; } + align-items: center; } .footer-page a { color: black; } -.footer-page h1 { +.footer-page-title, .footer-page h1, .footer-page h2 { font-family: 'Inconsolata'; - font-size: 1.5em; color: #E08E79; letter-spacing: 3pt; - font-weight: lighter; } + font-weight: lighter; + text-transform: lowercase; } + +.footer-page h1 { + font-size: 1.5em; } + +.footer-page h2 { + font-size: 1.2em; + font-weight: bold; } + +.footer-page h2 a { + margin-right: -3pt; } .login-page { background: linear-gradient(#070a15, #252b46); diff --git a/public/css/main.css.map b/public/css/main.css.map index 8b471c6..7818bb2 100644 --- a/public/css/main.css.map +++ b/public/css/main.css.map @@ -1,6 +1,6 @@ { "version": 3, -"mappings": "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", +"mappings": "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", "sources": ["main.scss","navigation.sass","forms.sass"], "names": [], "file": "main.css" diff --git a/public/css/main.scss b/public/css/main.scss index 9e28d8f..f99bb8b 100644 --- a/public/css/main.scss +++ b/public/css/main.scss @@ -109,19 +109,35 @@ body { flex-direction: column; justify-content: center; align-items: center; - height: 20vh; } .footer-page a { color: black } -.footer-page h1 { + + +.footer-page-title { font-family: 'Inconsolata'; - font-size: 1.5em; color: #E08E79; letter-spacing: 3pt; font-weight: lighter; + text-transform: lowercase; +} + +.footer-page h1 { + @extend .footer-page-title; + font-size: 1.5em; +} + +.footer-page h2 { + @extend .footer-page-title; + font-size: 1.2em; + font-weight: bold; +} + +.footer-page h2 a { + margin-right: -3pt; } // login page diff --git a/public/index.php b/public/index.php index 628e66e..64c5a22 100644 --- a/public/index.php +++ b/public/index.php @@ -1,6 +1,6 @@ ' + contributor.login + ''; + })); + + Zerooo.select('#contributors').innerHTML = html; + Zerooo.select('#contributors-container').style.display = 'block'; + }); +}); \ No newline at end of file diff --git a/public/js/zerooo.js b/public/js/zerooo.js new file mode 100644 index 0000000..f57c5e2 --- /dev/null +++ b/public/js/zerooo.js @@ -0,0 +1,81 @@ +Zerooo = {}; + +Zerooo.getJSON = function (url, callback) { + var x = new XMLHttpRequest(); + var callbackSent = false; + + x.open("GET", url, true); + x.onerror = function (message, source, lineno, colno, error) { + if (!callbackSent) { + sendCallback(error); + } + }; + + x.onreadystatechange = function () { + if (x.readyState != 4) return; + + if (x.status !== 200) { + sendCallback(new Error(url + " responded with status code " + x.status)); + return; + } + + var data = x.responseText; + var json = null; + + try { + json = JSON.parse(data); + } catch (e) { + sendCallback(e) + } + + sendCallback(null, json); + }; + x.send(); + + function sendCallback(err, data) + { + if (!callbackSent) { + callbackSent = true; + callback(err, data || null); + } + } +}; + +Zerooo.whenReady = function (callback) { + if (document.readyState == "complete") { + setTimeout(callback, 0); + return; + } + + document.onreadystatechange = function () { + if (document.readyState == "complete") { + callback(); + } + } +}; + +Zerooo.select = function (sel) { + return document.querySelector(sel); +}; + +Zerooo.selectAll = function (sel) { + return document.querySelectorAll(sel); +}; + +Zerooo.joinHumanReadable = function (arr) { + if (arr.length === 0) { + return ""; + } + + if (arr.length === 1) { + return arr.shift(); + } + + var str = arr.shift(); + + while (arr.length > 1) { + str += ', ' + arr.shift(); + } + + return str + " and " + arr.shift(); +}; \ No newline at end of file diff --git a/src/Core.php b/src/Core.php index 179ecf7..4eb17ef 100644 --- a/src/Core.php +++ b/src/Core.php @@ -362,5 +362,4 @@ class Core implements ContainerInterface { $this->getSlim()->run(); } - } \ No newline at end of file diff --git a/src/Handler/Home.php b/src/Handler/Home.php index 46f8c2a..d9e532a 100644 --- a/src/Handler/Home.php +++ b/src/Handler/Home.php @@ -2,10 +2,31 @@ namespace Eater\Glim\Handler; +use Eater\Glim\Service\GitHub; + class Home extends Session { function handle() { - return $this->render("home.html.twig"); + /** @var GitHub $github */ + $github = $this->get('github'); + + /** @var string $repo */ + $repo = $this->get('github-repo'); + + /** @var string $author */ + $author = $this->get('author'); + + $info = $github->getRepoInfo(); + + if ($info !== false) { + $author = $info['owner']['login']; + } + + return $this->render("home.html.twig", [ + 'author' => $author, + 'contributors' => $github->getContributors(), + 'githubRepo' => $repo + ]); } } \ No newline at end of file diff --git a/src/Service/GitHub.php b/src/Service/GitHub.php new file mode 100644 index 0000000..ad13822 --- /dev/null +++ b/src/Service/GitHub.php @@ -0,0 +1,85 @@ +get('stash'); + + $contributors = $pool->getItem('github/contributors'); + + if ($contributors->isMiss()) { + $contributorsData = []; + + try { + $contributorsJson = @$this->fetch('/repos/' . $this->get('github-repo') . '/contributors'); + $contributorsNewData = json_decode($contributorsJson, true); + if ($contributorsNewData !== null) { + $contributorsData = $contributorsNewData; + } + } catch (\Exception $e) { + } + + $info = $this->getRepoInfo(); + + if ($info !== false) { + + $ownerId = $info['owner']['id']; + + $contributorsNewData = []; + + foreach ($contributorsData as $contributor) { + if ($contributor['id'] !== $ownerId) { + $contributorsNewData[] = $contributor; + } + } + + $contributorsData = $contributorsNewData; + } + + $contributors->expiresAfter(3600); + $contributors->set($contributorsData); + $contributors->save(); + } + + return $contributors->get(); + } + + public function getRepoInfo() { + /** @var Pool $pool */ + $pool = $this->get('stash'); + + $info = $pool->getItem('github/info'); + + if ($info->isMiss()) { + $infoData = false; + + try { + $infoJson = @$this->fetch('/repos/' . $this->get('github-repo')); + $infoNewData = json_decode($infoJson, true); + if ($infoNewData !== null) { + $infoData = $infoNewData; + } + } catch (\Exception $e) { + } + + $info->expiresAfter(3600); + $info->set($infoData); + $info->save(); + } + + return $info->get(); + } + + private function fetch($path) + { + $options = array('http' => array('user_agent'=> $_SERVER['HTTP_USER_AGENT'])); + $context = stream_context_create($options); + return file_get_contents('https://api.github.com' . $path, false, $context); + } +} \ No newline at end of file diff --git a/src/Service/Stash.php b/src/Service/Stash.php new file mode 100644 index 0000000..2bc2aba --- /dev/null +++ b/src/Service/Stash.php @@ -0,0 +1,15 @@ + + +{% endblock %} {% block content %}
@@ -36,7 +40,15 @@
{% endblock %} From b712668bf3b6696c8d1aef4028f564fed832e7be Mon Sep 17 00:00:00 2001 From: Corne Oppelaar Date: Sun, 19 Jun 2016 19:51:43 +0200 Subject: [PATCH 3/7] remove zerooo.js and home.js since fetching contributors in now done in php --- public/js/home.js | 17 ---------- public/js/zerooo.js | 81 -------------------------------------------- views/home.html.twig | 4 --- 3 files changed, 102 deletions(-) delete mode 100644 public/js/home.js delete mode 100644 public/js/zerooo.js diff --git a/public/js/home.js b/public/js/home.js deleted file mode 100644 index ce9b437..0000000 --- a/public/js/home.js +++ /dev/null @@ -1,17 +0,0 @@ -Zerooo.whenReady(function() { - Zerooo.getJSON('https://api.github.com/repos/EaterOfCode/zer.ooo/contributors', function (err, data) { - if (err) return; - - var contributors = data.filter(function (data) { - // It's me! - return data.id !== 1922630; - }); - - var html = Zerooo.joinHumanReadable(contributors.map(function (contributor) { - return '' + contributor.login + ''; - })); - - Zerooo.select('#contributors').innerHTML = html; - Zerooo.select('#contributors-container').style.display = 'block'; - }); -}); \ No newline at end of file diff --git a/public/js/zerooo.js b/public/js/zerooo.js deleted file mode 100644 index f57c5e2..0000000 --- a/public/js/zerooo.js +++ /dev/null @@ -1,81 +0,0 @@ -Zerooo = {}; - -Zerooo.getJSON = function (url, callback) { - var x = new XMLHttpRequest(); - var callbackSent = false; - - x.open("GET", url, true); - x.onerror = function (message, source, lineno, colno, error) { - if (!callbackSent) { - sendCallback(error); - } - }; - - x.onreadystatechange = function () { - if (x.readyState != 4) return; - - if (x.status !== 200) { - sendCallback(new Error(url + " responded with status code " + x.status)); - return; - } - - var data = x.responseText; - var json = null; - - try { - json = JSON.parse(data); - } catch (e) { - sendCallback(e) - } - - sendCallback(null, json); - }; - x.send(); - - function sendCallback(err, data) - { - if (!callbackSent) { - callbackSent = true; - callback(err, data || null); - } - } -}; - -Zerooo.whenReady = function (callback) { - if (document.readyState == "complete") { - setTimeout(callback, 0); - return; - } - - document.onreadystatechange = function () { - if (document.readyState == "complete") { - callback(); - } - } -}; - -Zerooo.select = function (sel) { - return document.querySelector(sel); -}; - -Zerooo.selectAll = function (sel) { - return document.querySelectorAll(sel); -}; - -Zerooo.joinHumanReadable = function (arr) { - if (arr.length === 0) { - return ""; - } - - if (arr.length === 1) { - return arr.shift(); - } - - var str = arr.shift(); - - while (arr.length > 1) { - str += ', ' + arr.shift(); - } - - return str + " and " + arr.shift(); -}; \ No newline at end of file diff --git a/views/home.html.twig b/views/home.html.twig index 4b1de1a..c4790a4 100644 --- a/views/home.html.twig +++ b/views/home.html.twig @@ -1,8 +1,4 @@ {% extends "base.html.twig" %} -{% block head %} - - -{% endblock %} {% block content %}
From a82f762949b42e49d1c5386fda22f0f3b2ee5875 Mon Sep 17 00:00:00 2001 From: Corne Oppelaar Date: Tue, 21 Jun 2016 01:21:32 +0200 Subject: [PATCH 4/7] add invite system schema changes --- config/schema.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/config/schema.xml b/config/schema.xml index 1a782f1..4e4aa2b 100644 --- a/config/schema.xml +++ b/config/schema.xml @@ -9,6 +9,8 @@ + + @@ -46,6 +48,11 @@ + + + + +
From ddc87ffeed519e1dbc7ab98fe58b501dbd4939d6 Mon Sep 17 00:00:00 2001 From: Corne Oppelaar Date: Tue, 21 Jun 2016 01:22:47 +0200 Subject: [PATCH 5/7] regenerate User model after schema change --- src/Model/Base/Invite.php | 164 +++++++++++- src/Model/Base/InviteQuery.php | 136 +++++++++- src/Model/Base/User.php | 416 ++++++++++++++++++++++++++++++- src/Model/Base/UserQuery.php | 175 ++++++++++++- src/Model/Map/InviteTableMap.php | 39 ++- src/Model/Map/UserTableMap.php | 47 +++- 6 files changed, 945 insertions(+), 32 deletions(-) diff --git a/src/Model/Base/Invite.php b/src/Model/Base/Invite.php index 3cf8a69..96da6de 100644 --- a/src/Model/Base/Invite.php +++ b/src/Model/Base/Invite.php @@ -5,6 +5,8 @@ namespace Eater\Glim\Model\Base; use \Exception; use \PDO; use Eater\Glim\Model\InviteQuery as ChildInviteQuery; +use Eater\Glim\Model\User as ChildUser; +use Eater\Glim\Model\UserQuery as ChildUserQuery; use Eater\Glim\Model\Map\InviteTableMap; use Propel\Runtime\Propel; use Propel\Runtime\ActiveQuery\Criteria; @@ -71,6 +73,17 @@ abstract class Invite implements ActiveRecordInterface */ protected $invite; + /** + * The value for the owner field. + * @var int + */ + protected $owner; + + /** + * @var ChildUser + */ + protected $aUser; + /** * Flag to prevent endless save loop, if this object is referenced * by another object which falls in this transaction. @@ -316,6 +329,16 @@ abstract class Invite implements ActiveRecordInterface return $this->invite; } + /** + * Get the [owner] column value. + * + * @return int + */ + public function getOwner() + { + return $this->owner; + } + /** * Set the value of [id] column. * @@ -356,6 +379,30 @@ abstract class Invite implements ActiveRecordInterface return $this; } // setInvite() + /** + * Set the value of [owner] column. + * + * @param int $v new value + * @return $this|\Eater\Glim\Model\Invite The current object (for fluent API support) + */ + public function setOwner($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->owner !== $v) { + $this->owner = $v; + $this->modifiedColumns[InviteTableMap::COL_OWNER] = true; + } + + if ($this->aUser !== null && $this->aUser->getId() !== $v) { + $this->aUser = null; + } + + return $this; + } // setOwner() + /** * Indicates whether the columns in this object are only set to default values. * @@ -397,6 +444,9 @@ abstract class Invite implements ActiveRecordInterface $col = $row[TableMap::TYPE_NUM == $indexType ? 1 + $startcol : InviteTableMap::translateFieldName('Invite', TableMap::TYPE_PHPNAME, $indexType)]; $this->invite = (null !== $col) ? (string) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 2 + $startcol : InviteTableMap::translateFieldName('Owner', TableMap::TYPE_PHPNAME, $indexType)]; + $this->owner = (null !== $col) ? (int) $col : null; $this->resetModified(); $this->setNew(false); @@ -405,7 +455,7 @@ abstract class Invite implements ActiveRecordInterface $this->ensureConsistency(); } - return $startcol + 2; // 2 = InviteTableMap::NUM_HYDRATE_COLUMNS. + return $startcol + 3; // 3 = InviteTableMap::NUM_HYDRATE_COLUMNS. } catch (Exception $e) { throw new PropelException(sprintf('Error populating %s object', '\\Eater\\Glim\\Model\\Invite'), 0, $e); @@ -427,6 +477,9 @@ abstract class Invite implements ActiveRecordInterface */ public function ensureConsistency() { + if ($this->aUser !== null && $this->owner !== $this->aUser->getId()) { + $this->aUser = null; + } } // ensureConsistency /** @@ -466,6 +519,7 @@ abstract class Invite implements ActiveRecordInterface if ($deep) { // also de-associate any related objects? + $this->aUser = null; } // if (deep) } @@ -565,6 +619,18 @@ abstract class Invite implements ActiveRecordInterface if (!$this->alreadyInSave) { $this->alreadyInSave = true; + // We call the save method on the following object(s) if they + // were passed to this object by their corresponding set + // method. This object relates to these object(s) by a + // foreign key reference. + + if ($this->aUser !== null) { + if ($this->aUser->isModified() || $this->aUser->isNew()) { + $affectedRows += $this->aUser->save($con); + } + $this->setUser($this->aUser); + } + if ($this->isNew() || $this->isModified()) { // persist changes if ($this->isNew()) { @@ -608,6 +674,9 @@ abstract class Invite implements ActiveRecordInterface if ($this->isColumnModified(InviteTableMap::COL_INVITE)) { $modifiedColumns[':p' . $index++] = 'invite'; } + if ($this->isColumnModified(InviteTableMap::COL_OWNER)) { + $modifiedColumns[':p' . $index++] = 'owner'; + } $sql = sprintf( 'INSERT INTO Invite (%s) VALUES (%s)', @@ -625,6 +694,9 @@ abstract class Invite implements ActiveRecordInterface case 'invite': $stmt->bindValue($identifier, $this->invite, PDO::PARAM_STR); break; + case 'owner': + $stmt->bindValue($identifier, $this->owner, PDO::PARAM_INT); + break; } } $stmt->execute(); @@ -693,6 +765,9 @@ abstract class Invite implements ActiveRecordInterface case 1: return $this->getInvite(); break; + case 2: + return $this->getOwner(); + break; default: return null; break; @@ -710,10 +785,11 @@ abstract class Invite implements ActiveRecordInterface * Defaults to TableMap::TYPE_PHPNAME. * @param boolean $includeLazyLoadColumns (optional) Whether to include lazy loaded columns. Defaults to TRUE. * @param array $alreadyDumpedObjects List of objects to skip to avoid recursion + * @param boolean $includeForeignObjects (optional) Whether to include hydrated related objects. Default to FALSE. * * @return array an associative array containing the field names (as keys) and field values */ - public function toArray($keyType = TableMap::TYPE_PHPNAME, $includeLazyLoadColumns = true, $alreadyDumpedObjects = array()) + public function toArray($keyType = TableMap::TYPE_PHPNAME, $includeLazyLoadColumns = true, $alreadyDumpedObjects = array(), $includeForeignObjects = false) { if (isset($alreadyDumpedObjects['Invite'][$this->hashCode()])) { @@ -724,12 +800,30 @@ abstract class Invite implements ActiveRecordInterface $result = array( $keys[0] => $this->getId(), $keys[1] => $this->getInvite(), + $keys[2] => $this->getOwner(), ); $virtualColumns = $this->virtualColumns; foreach ($virtualColumns as $key => $virtualColumn) { $result[$key] = $virtualColumn; } + if ($includeForeignObjects) { + if (null !== $this->aUser) { + + switch ($keyType) { + case TableMap::TYPE_CAMELNAME: + $key = 'user'; + break; + case TableMap::TYPE_FIELDNAME: + $key = 'User'; + break; + default: + $key = 'User'; + } + + $result[$key] = $this->aUser->toArray($keyType, $includeLazyLoadColumns, $alreadyDumpedObjects, true); + } + } return $result; } @@ -769,6 +863,9 @@ abstract class Invite implements ActiveRecordInterface case 1: $this->setInvite($value); break; + case 2: + $this->setOwner($value); + break; } // switch() return $this; @@ -801,6 +898,9 @@ abstract class Invite implements ActiveRecordInterface if (array_key_exists($keys[1], $arr)) { $this->setInvite($arr[$keys[1]]); } + if (array_key_exists($keys[2], $arr)) { + $this->setOwner($arr[$keys[2]]); + } } /** @@ -848,6 +948,9 @@ abstract class Invite implements ActiveRecordInterface if ($this->isColumnModified(InviteTableMap::COL_INVITE)) { $criteria->add(InviteTableMap::COL_INVITE, $this->invite); } + if ($this->isColumnModified(InviteTableMap::COL_OWNER)) { + $criteria->add(InviteTableMap::COL_OWNER, $this->owner); + } return $criteria; } @@ -935,6 +1038,7 @@ abstract class Invite implements ActiveRecordInterface public function copyInto($copyObj, $deepCopy = false, $makeNew = true) { $copyObj->setInvite($this->getInvite()); + $copyObj->setOwner($this->getOwner()); if ($makeNew) { $copyObj->setNew(true); $copyObj->setId(NULL); // this is a auto-increment column, so set to default value @@ -963,6 +1067,57 @@ abstract class Invite implements ActiveRecordInterface return $copyObj; } + /** + * Declares an association between this object and a ChildUser object. + * + * @param ChildUser $v + * @return $this|\Eater\Glim\Model\Invite The current object (for fluent API support) + * @throws PropelException + */ + public function setUser(ChildUser $v = null) + { + if ($v === null) { + $this->setOwner(NULL); + } else { + $this->setOwner($v->getId()); + } + + $this->aUser = $v; + + // Add binding for other direction of this n:n relationship. + // If this object has already been added to the ChildUser object, it will not be re-added. + if ($v !== null) { + $v->addInvite($this); + } + + + return $this; + } + + + /** + * Get the associated ChildUser object + * + * @param ConnectionInterface $con Optional Connection object. + * @return ChildUser The associated ChildUser object. + * @throws PropelException + */ + public function getUser(ConnectionInterface $con = null) + { + if ($this->aUser === null && ($this->owner !== null)) { + $this->aUser = ChildUserQuery::create()->findPk($this->owner, $con); + /* The following can be used additionally to + guarantee the related object contains a reference + to this object. This level of coupling may, however, be + undesirable since it could result in an only partially populated collection + in the referenced object. + $this->aUser->addInvites($this); + */ + } + + return $this->aUser; + } + /** * Clears the current object, sets all attributes to their default values and removes * outgoing references as well as back-references (from other objects to this one. Results probably in a database @@ -970,8 +1125,12 @@ abstract class Invite implements ActiveRecordInterface */ public function clear() { + if (null !== $this->aUser) { + $this->aUser->removeInvite($this); + } $this->id = null; $this->invite = null; + $this->owner = null; $this->alreadyInSave = false; $this->clearAllReferences(); $this->resetModified(); @@ -992,6 +1151,7 @@ abstract class Invite implements ActiveRecordInterface if ($deep) { } // if ($deep) + $this->aUser = null; } /** diff --git a/src/Model/Base/InviteQuery.php b/src/Model/Base/InviteQuery.php index 022540b..716c54c 100644 --- a/src/Model/Base/InviteQuery.php +++ b/src/Model/Base/InviteQuery.php @@ -10,6 +10,7 @@ use Eater\Glim\Model\Map\InviteTableMap; use Propel\Runtime\Propel; use Propel\Runtime\ActiveQuery\Criteria; use Propel\Runtime\ActiveQuery\ModelCriteria; +use Propel\Runtime\ActiveQuery\ModelJoin; use Propel\Runtime\Collection\ObjectCollection; use Propel\Runtime\Connection\ConnectionInterface; use Propel\Runtime\Exception\PropelException; @@ -21,29 +22,40 @@ use Propel\Runtime\Exception\PropelException; * * @method ChildInviteQuery orderById($order = Criteria::ASC) Order by the id column * @method ChildInviteQuery orderByInvite($order = Criteria::ASC) Order by the invite column + * @method ChildInviteQuery orderByOwner($order = Criteria::ASC) Order by the owner column * * @method ChildInviteQuery groupById() Group by the id column * @method ChildInviteQuery groupByInvite() Group by the invite column + * @method ChildInviteQuery groupByOwner() Group by the owner column * * @method ChildInviteQuery leftJoin($relation) Adds a LEFT JOIN clause to the query * @method ChildInviteQuery rightJoin($relation) Adds a RIGHT JOIN clause to the query * @method ChildInviteQuery innerJoin($relation) Adds a INNER JOIN clause to the query * + * @method ChildInviteQuery leftJoinUser($relationAlias = null) Adds a LEFT JOIN clause to the query using the User relation + * @method ChildInviteQuery rightJoinUser($relationAlias = null) Adds a RIGHT JOIN clause to the query using the User relation + * @method ChildInviteQuery innerJoinUser($relationAlias = null) Adds a INNER JOIN clause to the query using the User relation + * + * @method \Eater\Glim\Model\UserQuery endUse() Finalizes a secondary criteria and merges it with its primary Criteria + * * @method ChildInvite findOne(ConnectionInterface $con = null) Return the first ChildInvite matching the query * @method ChildInvite findOneOrCreate(ConnectionInterface $con = null) Return the first ChildInvite matching the query, or a new ChildInvite object populated from the query conditions when no match is found * * @method ChildInvite findOneById(int $id) Return the first ChildInvite filtered by the id column - * @method ChildInvite findOneByInvite(string $invite) Return the first ChildInvite filtered by the invite column * + * @method ChildInvite findOneByInvite(string $invite) Return the first ChildInvite filtered by the invite column + * @method ChildInvite findOneByOwner(int $owner) Return the first ChildInvite filtered by the owner column * * @method ChildInvite requirePk($key, ConnectionInterface $con = null) Return the ChildInvite by primary key and throws \Propel\Runtime\Exception\EntityNotFoundException when not found * @method ChildInvite requireOne(ConnectionInterface $con = null) Return the first ChildInvite matching the query and throws \Propel\Runtime\Exception\EntityNotFoundException when not found * * @method ChildInvite requireOneById(int $id) Return the first ChildInvite filtered by the id column and throws \Propel\Runtime\Exception\EntityNotFoundException when not found * @method ChildInvite requireOneByInvite(string $invite) Return the first ChildInvite filtered by the invite column and throws \Propel\Runtime\Exception\EntityNotFoundException when not found + * @method ChildInvite requireOneByOwner(int $owner) Return the first ChildInvite filtered by the owner column and throws \Propel\Runtime\Exception\EntityNotFoundException when not found * * @method ChildInvite[]|ObjectCollection find(ConnectionInterface $con = null) Return ChildInvite objects based on current ModelCriteria * @method ChildInvite[]|ObjectCollection findById(int $id) Return ChildInvite objects filtered by the id column * @method ChildInvite[]|ObjectCollection findByInvite(string $invite) Return ChildInvite objects filtered by the invite column + * @method ChildInvite[]|ObjectCollection findByOwner(int $owner) Return ChildInvite objects filtered by the owner column * @method ChildInvite[]|\Propel\Runtime\Util\PropelModelPager paginate($page = 1, $maxPerPage = 10, ConnectionInterface $con = null) Issue a SELECT query based on the current ModelCriteria and uses a page and a maximum number of results per page to compute an offset and a limit * */ @@ -136,7 +148,7 @@ abstract class InviteQuery extends ModelCriteria */ protected function findPkSimple($key, ConnectionInterface $con) { - $sql = 'SELECT id, invite FROM Invite WHERE id = :p0'; + $sql = 'SELECT id, invite, owner FROM Invite WHERE id = :p0'; try { $stmt = $con->prepare($sql); $stmt->bindValue(':p0', $key, PDO::PARAM_INT); @@ -296,6 +308,126 @@ abstract class InviteQuery extends ModelCriteria return $this->addUsingAlias(InviteTableMap::COL_INVITE, $invite, $comparison); } + /** + * Filter the query on the owner column + * + * Example usage: + * + * $query->filterByOwner(1234); // WHERE owner = 1234 + * $query->filterByOwner(array(12, 34)); // WHERE owner IN (12, 34) + * $query->filterByOwner(array('min' => 12)); // WHERE owner > 12 + * + * + * @see filterByUser() + * + * @param mixed $owner The value to use as filter. + * Use scalar values for equality. + * Use array values for in_array() equivalent. + * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return $this|ChildInviteQuery The current query, for fluid interface + */ + public function filterByOwner($owner = null, $comparison = null) + { + if (is_array($owner)) { + $useMinMax = false; + if (isset($owner['min'])) { + $this->addUsingAlias(InviteTableMap::COL_OWNER, $owner['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($owner['max'])) { + $this->addUsingAlias(InviteTableMap::COL_OWNER, $owner['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(InviteTableMap::COL_OWNER, $owner, $comparison); + } + + /** + * Filter the query by a related \Eater\Glim\Model\User object + * + * @param \Eater\Glim\Model\User|ObjectCollection $user The related object(s) to use as filter + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @throws \Propel\Runtime\Exception\PropelException + * + * @return ChildInviteQuery The current query, for fluid interface + */ + public function filterByUser($user, $comparison = null) + { + if ($user instanceof \Eater\Glim\Model\User) { + return $this + ->addUsingAlias(InviteTableMap::COL_OWNER, $user->getId(), $comparison); + } elseif ($user instanceof ObjectCollection) { + if (null === $comparison) { + $comparison = Criteria::IN; + } + + return $this + ->addUsingAlias(InviteTableMap::COL_OWNER, $user->toKeyValue('PrimaryKey', 'Id'), $comparison); + } else { + throw new PropelException('filterByUser() only accepts arguments of type \Eater\Glim\Model\User or Collection'); + } + } + + /** + * Adds a JOIN clause to the query using the User relation + * + * @param string $relationAlias optional alias for the relation + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return $this|ChildInviteQuery The current query, for fluid interface + */ + public function joinUser($relationAlias = null, $joinType = Criteria::LEFT_JOIN) + { + $tableMap = $this->getTableMap(); + $relationMap = $tableMap->getRelation('User'); + + // create a ModelJoin object for this join + $join = new ModelJoin(); + $join->setJoinType($joinType); + $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); + if ($previousJoin = $this->getPreviousJoin()) { + $join->setPreviousJoin($previousJoin); + } + + // add the ModelJoin to the current object + if ($relationAlias) { + $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); + $this->addJoinObject($join, $relationAlias); + } else { + $this->addJoinObject($join, 'User'); + } + + return $this; + } + + /** + * Use the User relation User object + * + * @see useQuery() + * + * @param string $relationAlias optional alias for the relation, + * to be used as main alias in the secondary query + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return \Eater\Glim\Model\UserQuery A secondary query class using the current class as primary query + */ + public function useUserQuery($relationAlias = null, $joinType = Criteria::LEFT_JOIN) + { + return $this + ->joinUser($relationAlias, $joinType) + ->useQuery($relationAlias ? $relationAlias : 'User', '\Eater\Glim\Model\UserQuery'); + } + /** * Exclude object from result * diff --git a/src/Model/Base/User.php b/src/Model/Base/User.php index 83a33a9..fe52815 100644 --- a/src/Model/Base/User.php +++ b/src/Model/Base/User.php @@ -6,6 +6,8 @@ use \Exception; use \PDO; use Eater\Glim\Model\Certificate as ChildCertificate; use Eater\Glim\Model\CertificateQuery as ChildCertificateQuery; +use Eater\Glim\Model\Invite as ChildInvite; +use Eater\Glim\Model\InviteQuery as ChildInviteQuery; use Eater\Glim\Model\User as ChildUser; use Eater\Glim\Model\UserQuery as ChildUserQuery; use Eater\Glim\Model\Map\UserTableMap; @@ -95,12 +97,32 @@ abstract class User implements ActiveRecordInterface */ protected $superuser; + /** + * The value for the max_invites field. + * Note: this column has a database default value of: 0 + * @var int + */ + protected $max_invites; + + /** + * The value for the used_invites field. + * Note: this column has a database default value of: 0 + * @var int + */ + protected $used_invites; + /** * @var ObjectCollection|ChildCertificate[] Collection to store aggregation of ChildCertificate objects. */ protected $collCertificates; protected $collCertificatesPartial; + /** + * @var ObjectCollection|ChildInvite[] Collection to store aggregation of ChildInvite objects. + */ + protected $collInvites; + protected $collInvitesPartial; + /** * Flag to prevent endless save loop, if this object is referenced * by another object which falls in this transaction. @@ -115,6 +137,12 @@ abstract class User implements ActiveRecordInterface */ protected $certificatesScheduledForDeletion = null; + /** + * An array of objects scheduled for deletion. + * @var ObjectCollection|ChildInvite[] + */ + protected $invitesScheduledForDeletion = null; + /** * Applies default values to this object. * This method should be called from the object's constructor (or @@ -125,6 +153,8 @@ abstract class User implements ActiveRecordInterface { $this->max_keys = 5; $this->superuser = false; + $this->max_invites = 0; + $this->used_invites = 0; } /** @@ -406,6 +436,26 @@ abstract class User implements ActiveRecordInterface return $this->getSuperuser(); } + /** + * Get the [max_invites] column value. + * + * @return int + */ + public function getMaxInvites() + { + return $this->max_invites; + } + + /** + * Get the [used_invites] column value. + * + * @return int + */ + public function getUsedInvites() + { + return $this->used_invites; + } + /** * Set the value of [id] column. * @@ -514,6 +564,46 @@ abstract class User implements ActiveRecordInterface return $this; } // setSuperuser() + /** + * Set the value of [max_invites] column. + * + * @param int $v new value + * @return $this|\Eater\Glim\Model\User The current object (for fluent API support) + */ + public function setMaxInvites($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->max_invites !== $v) { + $this->max_invites = $v; + $this->modifiedColumns[UserTableMap::COL_MAX_INVITES] = true; + } + + return $this; + } // setMaxInvites() + + /** + * Set the value of [used_invites] column. + * + * @param int $v new value + * @return $this|\Eater\Glim\Model\User The current object (for fluent API support) + */ + public function setUsedInvites($v) + { + if ($v !== null) { + $v = (int) $v; + } + + if ($this->used_invites !== $v) { + $this->used_invites = $v; + $this->modifiedColumns[UserTableMap::COL_USED_INVITES] = true; + } + + return $this; + } // setUsedInvites() + /** * Indicates whether the columns in this object are only set to default values. * @@ -532,6 +622,14 @@ abstract class User implements ActiveRecordInterface return false; } + if ($this->max_invites !== 0) { + return false; + } + + if ($this->used_invites !== 0) { + return false; + } + // otherwise, everything was equal, so return TRUE return true; } // hasOnlyDefaultValues() @@ -572,6 +670,12 @@ abstract class User implements ActiveRecordInterface $col = $row[TableMap::TYPE_NUM == $indexType ? 4 + $startcol : UserTableMap::translateFieldName('Superuser', TableMap::TYPE_PHPNAME, $indexType)]; $this->superuser = (null !== $col) ? (boolean) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 5 + $startcol : UserTableMap::translateFieldName('MaxInvites', TableMap::TYPE_PHPNAME, $indexType)]; + $this->max_invites = (null !== $col) ? (int) $col : null; + + $col = $row[TableMap::TYPE_NUM == $indexType ? 6 + $startcol : UserTableMap::translateFieldName('UsedInvites', TableMap::TYPE_PHPNAME, $indexType)]; + $this->used_invites = (null !== $col) ? (int) $col : null; $this->resetModified(); $this->setNew(false); @@ -580,7 +684,7 @@ abstract class User implements ActiveRecordInterface $this->ensureConsistency(); } - return $startcol + 5; // 5 = UserTableMap::NUM_HYDRATE_COLUMNS. + return $startcol + 7; // 7 = UserTableMap::NUM_HYDRATE_COLUMNS. } catch (Exception $e) { throw new PropelException(sprintf('Error populating %s object', '\\Eater\\Glim\\Model\\User'), 0, $e); @@ -643,6 +747,8 @@ abstract class User implements ActiveRecordInterface $this->collCertificates = null; + $this->collInvites = null; + } // if (deep) } @@ -771,6 +877,24 @@ abstract class User implements ActiveRecordInterface } } + if ($this->invitesScheduledForDeletion !== null) { + if (!$this->invitesScheduledForDeletion->isEmpty()) { + foreach ($this->invitesScheduledForDeletion as $invite) { + // need to save related object because we set the relation to null + $invite->save($con); + } + $this->invitesScheduledForDeletion = null; + } + } + + if ($this->collInvites !== null) { + foreach ($this->collInvites as $referrerFK) { + if (!$referrerFK->isDeleted() && ($referrerFK->isNew() || $referrerFK->isModified())) { + $affectedRows += $referrerFK->save($con); + } + } + } + $this->alreadyInSave = false; } @@ -812,6 +936,12 @@ abstract class User implements ActiveRecordInterface if ($this->isColumnModified(UserTableMap::COL_SUPERUSER)) { $modifiedColumns[':p' . $index++] = 'superuser'; } + if ($this->isColumnModified(UserTableMap::COL_MAX_INVITES)) { + $modifiedColumns[':p' . $index++] = 'max_invites'; + } + if ($this->isColumnModified(UserTableMap::COL_USED_INVITES)) { + $modifiedColumns[':p' . $index++] = 'used_invites'; + } $sql = sprintf( 'INSERT INTO User (%s) VALUES (%s)', @@ -838,6 +968,12 @@ abstract class User implements ActiveRecordInterface case 'superuser': $stmt->bindValue($identifier, $this->superuser, PDO::PARAM_BOOL); break; + case 'max_invites': + $stmt->bindValue($identifier, $this->max_invites, PDO::PARAM_INT); + break; + case 'used_invites': + $stmt->bindValue($identifier, $this->used_invites, PDO::PARAM_INT); + break; } } $stmt->execute(); @@ -915,6 +1051,12 @@ abstract class User implements ActiveRecordInterface case 4: return $this->getSuperuser(); break; + case 5: + return $this->getMaxInvites(); + break; + case 6: + return $this->getUsedInvites(); + break; default: return null; break; @@ -950,6 +1092,8 @@ abstract class User implements ActiveRecordInterface $keys[2] => $this->getUsername(), $keys[3] => $this->getPassword(), $keys[4] => $this->getSuperuser(), + $keys[5] => $this->getMaxInvites(), + $keys[6] => $this->getUsedInvites(), ); $virtualColumns = $this->virtualColumns; foreach ($virtualColumns as $key => $virtualColumn) { @@ -972,6 +1116,21 @@ abstract class User implements ActiveRecordInterface $result[$key] = $this->collCertificates->toArray(null, false, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects); } + if (null !== $this->collInvites) { + + switch ($keyType) { + case TableMap::TYPE_CAMELNAME: + $key = 'invites'; + break; + case TableMap::TYPE_FIELDNAME: + $key = 'Invites'; + break; + default: + $key = 'Invites'; + } + + $result[$key] = $this->collInvites->toArray(null, false, $keyType, $includeLazyLoadColumns, $alreadyDumpedObjects); + } } return $result; @@ -1021,6 +1180,12 @@ abstract class User implements ActiveRecordInterface case 4: $this->setSuperuser($value); break; + case 5: + $this->setMaxInvites($value); + break; + case 6: + $this->setUsedInvites($value); + break; } // switch() return $this; @@ -1062,6 +1227,12 @@ abstract class User implements ActiveRecordInterface if (array_key_exists($keys[4], $arr)) { $this->setSuperuser($arr[$keys[4]]); } + if (array_key_exists($keys[5], $arr)) { + $this->setMaxInvites($arr[$keys[5]]); + } + if (array_key_exists($keys[6], $arr)) { + $this->setUsedInvites($arr[$keys[6]]); + } } /** @@ -1118,6 +1289,12 @@ abstract class User implements ActiveRecordInterface if ($this->isColumnModified(UserTableMap::COL_SUPERUSER)) { $criteria->add(UserTableMap::COL_SUPERUSER, $this->superuser); } + if ($this->isColumnModified(UserTableMap::COL_MAX_INVITES)) { + $criteria->add(UserTableMap::COL_MAX_INVITES, $this->max_invites); + } + if ($this->isColumnModified(UserTableMap::COL_USED_INVITES)) { + $criteria->add(UserTableMap::COL_USED_INVITES, $this->used_invites); + } return $criteria; } @@ -1208,6 +1385,8 @@ abstract class User implements ActiveRecordInterface $copyObj->setUsername($this->getUsername()); $copyObj->setPassword($this->getPassword()); $copyObj->setSuperuser($this->getSuperuser()); + $copyObj->setMaxInvites($this->getMaxInvites()); + $copyObj->setUsedInvites($this->getUsedInvites()); if ($deepCopy) { // important: temporarily setNew(false) because this affects the behavior of @@ -1220,6 +1399,12 @@ abstract class User implements ActiveRecordInterface } } + foreach ($this->getInvites() as $relObj) { + if ($relObj !== $this) { // ensure that we don't try to copy a reference to ourselves + $copyObj->addInvite($relObj->copy($deepCopy)); + } + } + } // if ($deepCopy) if ($makeNew) { @@ -1264,6 +1449,9 @@ abstract class User implements ActiveRecordInterface if ('Certificate' == $relationName) { return $this->initCertificates(); } + if ('Invite' == $relationName) { + return $this->initInvites(); + } } /** @@ -1484,6 +1672,224 @@ abstract class User implements ActiveRecordInterface return $this; } + /** + * Clears out the collInvites collection + * + * This does not modify the database; however, it will remove any associated objects, causing + * them to be refetched by subsequent calls to accessor method. + * + * @return void + * @see addInvites() + */ + public function clearInvites() + { + $this->collInvites = null; // important to set this to NULL since that means it is uninitialized + } + + /** + * Reset is the collInvites collection loaded partially. + */ + public function resetPartialInvites($v = true) + { + $this->collInvitesPartial = $v; + } + + /** + * Initializes the collInvites collection. + * + * By default this just sets the collInvites collection to an empty array (like clearcollInvites()); + * however, you may wish to override this method in your stub class to provide setting appropriate + * to your application -- for example, setting the initial array to the values stored in database. + * + * @param boolean $overrideExisting If set to true, the method call initializes + * the collection even if it is not empty + * + * @return void + */ + public function initInvites($overrideExisting = true) + { + if (null !== $this->collInvites && !$overrideExisting) { + return; + } + $this->collInvites = new ObjectCollection(); + $this->collInvites->setModel('\Eater\Glim\Model\Invite'); + } + + /** + * Gets an array of ChildInvite objects which contain a foreign key that references this object. + * + * If the $criteria is not null, it is used to always fetch the results from the database. + * Otherwise the results are fetched from the database the first time, then cached. + * Next time the same method is called without $criteria, the cached collection is returned. + * If this ChildUser is new, it will return + * an empty collection or the current collection; the criteria is ignored on a new object. + * + * @param Criteria $criteria optional Criteria object to narrow the query + * @param ConnectionInterface $con optional connection object + * @return ObjectCollection|ChildInvite[] List of ChildInvite objects + * @throws PropelException + */ + public function getInvites(Criteria $criteria = null, ConnectionInterface $con = null) + { + $partial = $this->collInvitesPartial && !$this->isNew(); + if (null === $this->collInvites || null !== $criteria || $partial) { + if ($this->isNew() && null === $this->collInvites) { + // return empty collection + $this->initInvites(); + } else { + $collInvites = ChildInviteQuery::create(null, $criteria) + ->filterByUser($this) + ->find($con); + + if (null !== $criteria) { + if (false !== $this->collInvitesPartial && count($collInvites)) { + $this->initInvites(false); + + foreach ($collInvites as $obj) { + if (false == $this->collInvites->contains($obj)) { + $this->collInvites->append($obj); + } + } + + $this->collInvitesPartial = true; + } + + return $collInvites; + } + + if ($partial && $this->collInvites) { + foreach ($this->collInvites as $obj) { + if ($obj->isNew()) { + $collInvites[] = $obj; + } + } + } + + $this->collInvites = $collInvites; + $this->collInvitesPartial = false; + } + } + + return $this->collInvites; + } + + /** + * Sets a collection of ChildInvite objects related by a one-to-many relationship + * to the current object. + * It will also schedule objects for deletion based on a diff between old objects (aka persisted) + * and new objects from the given Propel collection. + * + * @param Collection $invites A Propel collection. + * @param ConnectionInterface $con Optional connection object + * @return $this|ChildUser The current object (for fluent API support) + */ + public function setInvites(Collection $invites, ConnectionInterface $con = null) + { + /** @var ChildInvite[] $invitesToDelete */ + $invitesToDelete = $this->getInvites(new Criteria(), $con)->diff($invites); + + + $this->invitesScheduledForDeletion = $invitesToDelete; + + foreach ($invitesToDelete as $inviteRemoved) { + $inviteRemoved->setUser(null); + } + + $this->collInvites = null; + foreach ($invites as $invite) { + $this->addInvite($invite); + } + + $this->collInvites = $invites; + $this->collInvitesPartial = false; + + return $this; + } + + /** + * Returns the number of related Invite objects. + * + * @param Criteria $criteria + * @param boolean $distinct + * @param ConnectionInterface $con + * @return int Count of related Invite objects. + * @throws PropelException + */ + public function countInvites(Criteria $criteria = null, $distinct = false, ConnectionInterface $con = null) + { + $partial = $this->collInvitesPartial && !$this->isNew(); + if (null === $this->collInvites || null !== $criteria || $partial) { + if ($this->isNew() && null === $this->collInvites) { + return 0; + } + + if ($partial && !$criteria) { + return count($this->getInvites()); + } + + $query = ChildInviteQuery::create(null, $criteria); + if ($distinct) { + $query->distinct(); + } + + return $query + ->filterByUser($this) + ->count($con); + } + + return count($this->collInvites); + } + + /** + * Method called to associate a ChildInvite object to this object + * through the ChildInvite foreign key attribute. + * + * @param ChildInvite $l ChildInvite + * @return $this|\Eater\Glim\Model\User The current object (for fluent API support) + */ + public function addInvite(ChildInvite $l) + { + if ($this->collInvites === null) { + $this->initInvites(); + $this->collInvitesPartial = true; + } + + if (!$this->collInvites->contains($l)) { + $this->doAddInvite($l); + } + + return $this; + } + + /** + * @param ChildInvite $invite The ChildInvite object to add. + */ + protected function doAddInvite(ChildInvite $invite) + { + $this->collInvites[]= $invite; + $invite->setUser($this); + } + + /** + * @param ChildInvite $invite The ChildInvite object to remove. + * @return $this|ChildUser The current object (for fluent API support) + */ + public function removeInvite(ChildInvite $invite) + { + if ($this->getInvites()->contains($invite)) { + $pos = $this->collInvites->search($invite); + $this->collInvites->remove($pos); + if (null === $this->invitesScheduledForDeletion) { + $this->invitesScheduledForDeletion = clone $this->collInvites; + $this->invitesScheduledForDeletion->clear(); + } + $this->invitesScheduledForDeletion[]= $invite; + $invite->setUser(null); + } + + return $this; + } + /** * Clears the current object, sets all attributes to their default values and removes * outgoing references as well as back-references (from other objects to this one. Results probably in a database @@ -1496,6 +1902,8 @@ abstract class User implements ActiveRecordInterface $this->username = null; $this->password = null; $this->superuser = null; + $this->max_invites = null; + $this->used_invites = null; $this->alreadyInSave = false; $this->clearAllReferences(); $this->applyDefaultValues(); @@ -1520,9 +1928,15 @@ abstract class User implements ActiveRecordInterface $o->clearAllReferences($deep); } } + if ($this->collInvites) { + foreach ($this->collInvites as $o) { + $o->clearAllReferences($deep); + } + } } // if ($deep) $this->collCertificates = null; + $this->collInvites = null; } /** diff --git a/src/Model/Base/UserQuery.php b/src/Model/Base/UserQuery.php index 43fb663..39ec58d 100644 --- a/src/Model/Base/UserQuery.php +++ b/src/Model/Base/UserQuery.php @@ -25,12 +25,16 @@ use Propel\Runtime\Exception\PropelException; * @method ChildUserQuery orderByUsername($order = Criteria::ASC) Order by the username column * @method ChildUserQuery orderByPassword($order = Criteria::ASC) Order by the password column * @method ChildUserQuery orderBySuperuser($order = Criteria::ASC) Order by the superuser column + * @method ChildUserQuery orderByMaxInvites($order = Criteria::ASC) Order by the max_invites column + * @method ChildUserQuery orderByUsedInvites($order = Criteria::ASC) Order by the used_invites column * * @method ChildUserQuery groupById() Group by the id column * @method ChildUserQuery groupByMaxKeys() Group by the max_keys column * @method ChildUserQuery groupByUsername() Group by the username column * @method ChildUserQuery groupByPassword() Group by the password column * @method ChildUserQuery groupBySuperuser() Group by the superuser column + * @method ChildUserQuery groupByMaxInvites() Group by the max_invites column + * @method ChildUserQuery groupByUsedInvites() Group by the used_invites column * * @method ChildUserQuery leftJoin($relation) Adds a LEFT JOIN clause to the query * @method ChildUserQuery rightJoin($relation) Adds a RIGHT JOIN clause to the query @@ -40,7 +44,11 @@ use Propel\Runtime\Exception\PropelException; * @method ChildUserQuery rightJoinCertificate($relationAlias = null) Adds a RIGHT JOIN clause to the query using the Certificate relation * @method ChildUserQuery innerJoinCertificate($relationAlias = null) Adds a INNER JOIN clause to the query using the Certificate relation * - * @method \Eater\Glim\Model\CertificateQuery endUse() Finalizes a secondary criteria and merges it with its primary Criteria + * @method ChildUserQuery leftJoinInvite($relationAlias = null) Adds a LEFT JOIN clause to the query using the Invite relation + * @method ChildUserQuery rightJoinInvite($relationAlias = null) Adds a RIGHT JOIN clause to the query using the Invite relation + * @method ChildUserQuery innerJoinInvite($relationAlias = null) Adds a INNER JOIN clause to the query using the Invite relation + * + * @method \Eater\Glim\Model\CertificateQuery|\Eater\Glim\Model\InviteQuery endUse() Finalizes a secondary criteria and merges it with its primary Criteria * * @method ChildUser findOne(ConnectionInterface $con = null) Return the first ChildUser matching the query * @method ChildUser findOneOrCreate(ConnectionInterface $con = null) Return the first ChildUser matching the query, or a new ChildUser object populated from the query conditions when no match is found @@ -49,7 +57,9 @@ use Propel\Runtime\Exception\PropelException; * @method ChildUser findOneByMaxKeys(int $max_keys) Return the first ChildUser filtered by the max_keys column * @method ChildUser findOneByUsername(string $username) Return the first ChildUser filtered by the username column * @method ChildUser findOneByPassword(string $password) Return the first ChildUser filtered by the password column - * @method ChildUser findOneBySuperuser(boolean $superuser) Return the first ChildUser filtered by the superuser column * + * @method ChildUser findOneBySuperuser(boolean $superuser) Return the first ChildUser filtered by the superuser column + * @method ChildUser findOneByMaxInvites(int $max_invites) Return the first ChildUser filtered by the max_invites column + * @method ChildUser findOneByUsedInvites(int $used_invites) Return the first ChildUser filtered by the used_invites column * * @method ChildUser requirePk($key, ConnectionInterface $con = null) Return the ChildUser by primary key and throws \Propel\Runtime\Exception\EntityNotFoundException when not found * @method ChildUser requireOne(ConnectionInterface $con = null) Return the first ChildUser matching the query and throws \Propel\Runtime\Exception\EntityNotFoundException when not found @@ -59,6 +69,8 @@ use Propel\Runtime\Exception\PropelException; * @method ChildUser requireOneByUsername(string $username) Return the first ChildUser filtered by the username column and throws \Propel\Runtime\Exception\EntityNotFoundException when not found * @method ChildUser requireOneByPassword(string $password) Return the first ChildUser filtered by the password column and throws \Propel\Runtime\Exception\EntityNotFoundException when not found * @method ChildUser requireOneBySuperuser(boolean $superuser) Return the first ChildUser filtered by the superuser column and throws \Propel\Runtime\Exception\EntityNotFoundException when not found + * @method ChildUser requireOneByMaxInvites(int $max_invites) Return the first ChildUser filtered by the max_invites column and throws \Propel\Runtime\Exception\EntityNotFoundException when not found + * @method ChildUser requireOneByUsedInvites(int $used_invites) Return the first ChildUser filtered by the used_invites column and throws \Propel\Runtime\Exception\EntityNotFoundException when not found * * @method ChildUser[]|ObjectCollection find(ConnectionInterface $con = null) Return ChildUser objects based on current ModelCriteria * @method ChildUser[]|ObjectCollection findById(int $id) Return ChildUser objects filtered by the id column @@ -66,6 +78,8 @@ use Propel\Runtime\Exception\PropelException; * @method ChildUser[]|ObjectCollection findByUsername(string $username) Return ChildUser objects filtered by the username column * @method ChildUser[]|ObjectCollection findByPassword(string $password) Return ChildUser objects filtered by the password column * @method ChildUser[]|ObjectCollection findBySuperuser(boolean $superuser) Return ChildUser objects filtered by the superuser column + * @method ChildUser[]|ObjectCollection findByMaxInvites(int $max_invites) Return ChildUser objects filtered by the max_invites column + * @method ChildUser[]|ObjectCollection findByUsedInvites(int $used_invites) Return ChildUser objects filtered by the used_invites column * @method ChildUser[]|\Propel\Runtime\Util\PropelModelPager paginate($page = 1, $maxPerPage = 10, ConnectionInterface $con = null) Issue a SELECT query based on the current ModelCriteria and uses a page and a maximum number of results per page to compute an offset and a limit * */ @@ -158,7 +172,7 @@ abstract class UserQuery extends ModelCriteria */ protected function findPkSimple($key, ConnectionInterface $con) { - $sql = 'SELECT id, max_keys, username, password, superuser FROM User WHERE id = :p0'; + $sql = 'SELECT id, max_keys, username, password, superuser, max_invites, used_invites FROM User WHERE id = :p0'; try { $stmt = $con->prepare($sql); $stmt->bindValue(':p0', $key, PDO::PARAM_INT); @@ -415,6 +429,88 @@ abstract class UserQuery extends ModelCriteria return $this->addUsingAlias(UserTableMap::COL_SUPERUSER, $superuser, $comparison); } + /** + * Filter the query on the max_invites column + * + * Example usage: + * + * $query->filterByMaxInvites(1234); // WHERE max_invites = 1234 + * $query->filterByMaxInvites(array(12, 34)); // WHERE max_invites IN (12, 34) + * $query->filterByMaxInvites(array('min' => 12)); // WHERE max_invites > 12 + * + * + * @param mixed $maxInvites The value to use as filter. + * Use scalar values for equality. + * Use array values for in_array() equivalent. + * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return $this|ChildUserQuery The current query, for fluid interface + */ + public function filterByMaxInvites($maxInvites = null, $comparison = null) + { + if (is_array($maxInvites)) { + $useMinMax = false; + if (isset($maxInvites['min'])) { + $this->addUsingAlias(UserTableMap::COL_MAX_INVITES, $maxInvites['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($maxInvites['max'])) { + $this->addUsingAlias(UserTableMap::COL_MAX_INVITES, $maxInvites['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(UserTableMap::COL_MAX_INVITES, $maxInvites, $comparison); + } + + /** + * Filter the query on the used_invites column + * + * Example usage: + * + * $query->filterByUsedInvites(1234); // WHERE used_invites = 1234 + * $query->filterByUsedInvites(array(12, 34)); // WHERE used_invites IN (12, 34) + * $query->filterByUsedInvites(array('min' => 12)); // WHERE used_invites > 12 + * + * + * @param mixed $usedInvites The value to use as filter. + * Use scalar values for equality. + * Use array values for in_array() equivalent. + * Use associative array('min' => $minValue, 'max' => $maxValue) for intervals. + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return $this|ChildUserQuery The current query, for fluid interface + */ + public function filterByUsedInvites($usedInvites = null, $comparison = null) + { + if (is_array($usedInvites)) { + $useMinMax = false; + if (isset($usedInvites['min'])) { + $this->addUsingAlias(UserTableMap::COL_USED_INVITES, $usedInvites['min'], Criteria::GREATER_EQUAL); + $useMinMax = true; + } + if (isset($usedInvites['max'])) { + $this->addUsingAlias(UserTableMap::COL_USED_INVITES, $usedInvites['max'], Criteria::LESS_EQUAL); + $useMinMax = true; + } + if ($useMinMax) { + return $this; + } + if (null === $comparison) { + $comparison = Criteria::IN; + } + } + + return $this->addUsingAlias(UserTableMap::COL_USED_INVITES, $usedInvites, $comparison); + } + /** * Filter the query by a related \Eater\Glim\Model\Certificate object * @@ -488,6 +584,79 @@ abstract class UserQuery extends ModelCriteria ->useQuery($relationAlias ? $relationAlias : 'Certificate', '\Eater\Glim\Model\CertificateQuery'); } + /** + * Filter the query by a related \Eater\Glim\Model\Invite object + * + * @param \Eater\Glim\Model\Invite|ObjectCollection $invite the related object to use as filter + * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL + * + * @return ChildUserQuery The current query, for fluid interface + */ + public function filterByInvite($invite, $comparison = null) + { + if ($invite instanceof \Eater\Glim\Model\Invite) { + return $this + ->addUsingAlias(UserTableMap::COL_ID, $invite->getOwner(), $comparison); + } elseif ($invite instanceof ObjectCollection) { + return $this + ->useInviteQuery() + ->filterByPrimaryKeys($invite->getPrimaryKeys()) + ->endUse(); + } else { + throw new PropelException('filterByInvite() only accepts arguments of type \Eater\Glim\Model\Invite or Collection'); + } + } + + /** + * Adds a JOIN clause to the query using the Invite relation + * + * @param string $relationAlias optional alias for the relation + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return $this|ChildUserQuery The current query, for fluid interface + */ + public function joinInvite($relationAlias = null, $joinType = Criteria::LEFT_JOIN) + { + $tableMap = $this->getTableMap(); + $relationMap = $tableMap->getRelation('Invite'); + + // create a ModelJoin object for this join + $join = new ModelJoin(); + $join->setJoinType($joinType); + $join->setRelationMap($relationMap, $this->useAliasInSQL ? $this->getModelAlias() : null, $relationAlias); + if ($previousJoin = $this->getPreviousJoin()) { + $join->setPreviousJoin($previousJoin); + } + + // add the ModelJoin to the current object + if ($relationAlias) { + $this->addAlias($relationAlias, $relationMap->getRightTable()->getName()); + $this->addJoinObject($join, $relationAlias); + } else { + $this->addJoinObject($join, 'Invite'); + } + + return $this; + } + + /** + * Use the Invite relation Invite object + * + * @see useQuery() + * + * @param string $relationAlias optional alias for the relation, + * to be used as main alias in the secondary query + * @param string $joinType Accepted values are null, 'left join', 'right join', 'inner join' + * + * @return \Eater\Glim\Model\InviteQuery A secondary query class using the current class as primary query + */ + public function useInviteQuery($relationAlias = null, $joinType = Criteria::LEFT_JOIN) + { + return $this + ->joinInvite($relationAlias, $joinType) + ->useQuery($relationAlias ? $relationAlias : 'Invite', '\Eater\Glim\Model\InviteQuery'); + } + /** * Exclude object from result * diff --git a/src/Model/Map/InviteTableMap.php b/src/Model/Map/InviteTableMap.php index ba3713b..fab9b0f 100644 --- a/src/Model/Map/InviteTableMap.php +++ b/src/Model/Map/InviteTableMap.php @@ -59,7 +59,7 @@ class InviteTableMap extends TableMap /** * The total number of columns */ - const NUM_COLUMNS = 2; + const NUM_COLUMNS = 3; /** * The number of lazy-loaded columns @@ -69,7 +69,7 @@ class InviteTableMap extends TableMap /** * The number of columns to hydrate (NUM_COLUMNS - NUM_LAZY_LOAD_COLUMNS) */ - const NUM_HYDRATE_COLUMNS = 2; + const NUM_HYDRATE_COLUMNS = 3; /** * the column name for the id field @@ -81,6 +81,11 @@ class InviteTableMap extends TableMap */ const COL_INVITE = 'Invite.invite'; + /** + * the column name for the owner field + */ + const COL_OWNER = 'Invite.owner'; + /** * The default string format for model objects of the related table */ @@ -93,11 +98,11 @@ class InviteTableMap extends TableMap * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' */ protected static $fieldNames = array ( - self::TYPE_PHPNAME => array('Id', 'Invite', ), - self::TYPE_CAMELNAME => array('id', 'invite', ), - self::TYPE_COLNAME => array(InviteTableMap::COL_ID, InviteTableMap::COL_INVITE, ), - self::TYPE_FIELDNAME => array('id', 'invite', ), - self::TYPE_NUM => array(0, 1, ) + self::TYPE_PHPNAME => array('Id', 'Invite', 'Owner', ), + self::TYPE_CAMELNAME => array('id', 'invite', 'owner', ), + self::TYPE_COLNAME => array(InviteTableMap::COL_ID, InviteTableMap::COL_INVITE, InviteTableMap::COL_OWNER, ), + self::TYPE_FIELDNAME => array('id', 'invite', 'owner', ), + self::TYPE_NUM => array(0, 1, 2, ) ); /** @@ -107,11 +112,11 @@ class InviteTableMap extends TableMap * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 */ protected static $fieldKeys = array ( - self::TYPE_PHPNAME => array('Id' => 0, 'Invite' => 1, ), - self::TYPE_CAMELNAME => array('id' => 0, 'invite' => 1, ), - self::TYPE_COLNAME => array(InviteTableMap::COL_ID => 0, InviteTableMap::COL_INVITE => 1, ), - self::TYPE_FIELDNAME => array('id' => 0, 'invite' => 1, ), - self::TYPE_NUM => array(0, 1, ) + self::TYPE_PHPNAME => array('Id' => 0, 'Invite' => 1, 'Owner' => 2, ), + self::TYPE_CAMELNAME => array('id' => 0, 'invite' => 1, 'owner' => 2, ), + self::TYPE_COLNAME => array(InviteTableMap::COL_ID => 0, InviteTableMap::COL_INVITE => 1, InviteTableMap::COL_OWNER => 2, ), + self::TYPE_FIELDNAME => array('id' => 0, 'invite' => 1, 'owner' => 2, ), + self::TYPE_NUM => array(0, 1, 2, ) ); /** @@ -133,6 +138,7 @@ class InviteTableMap extends TableMap // columns $this->addPrimaryKey('id', 'Id', 'INTEGER', true, null, null); $this->addColumn('invite', 'Invite', 'VARCHAR', false, 64, null); + $this->addForeignKey('owner', 'Owner', 'INTEGER', 'User', 'id', false, null, null); } // initialize() /** @@ -140,6 +146,13 @@ class InviteTableMap extends TableMap */ public function buildRelations() { + $this->addRelation('User', '\\Eater\\Glim\\Model\\User', RelationMap::MANY_TO_ONE, array ( + 0 => + array ( + 0 => ':owner', + 1 => ':id', + ), +), null, null, null, false); } // buildRelations() /** @@ -285,9 +298,11 @@ class InviteTableMap extends TableMap if (null === $alias) { $criteria->addSelectColumn(InviteTableMap::COL_ID); $criteria->addSelectColumn(InviteTableMap::COL_INVITE); + $criteria->addSelectColumn(InviteTableMap::COL_OWNER); } else { $criteria->addSelectColumn($alias . '.id'); $criteria->addSelectColumn($alias . '.invite'); + $criteria->addSelectColumn($alias . '.owner'); } } diff --git a/src/Model/Map/UserTableMap.php b/src/Model/Map/UserTableMap.php index c70cf22..f59d8e2 100644 --- a/src/Model/Map/UserTableMap.php +++ b/src/Model/Map/UserTableMap.php @@ -59,7 +59,7 @@ class UserTableMap extends TableMap /** * The total number of columns */ - const NUM_COLUMNS = 5; + const NUM_COLUMNS = 7; /** * The number of lazy-loaded columns @@ -69,7 +69,7 @@ class UserTableMap extends TableMap /** * The number of columns to hydrate (NUM_COLUMNS - NUM_LAZY_LOAD_COLUMNS) */ - const NUM_HYDRATE_COLUMNS = 5; + const NUM_HYDRATE_COLUMNS = 7; /** * the column name for the id field @@ -96,6 +96,16 @@ class UserTableMap extends TableMap */ const COL_SUPERUSER = 'User.superuser'; + /** + * the column name for the max_invites field + */ + const COL_MAX_INVITES = 'User.max_invites'; + + /** + * the column name for the used_invites field + */ + const COL_USED_INVITES = 'User.used_invites'; + /** * The default string format for model objects of the related table */ @@ -108,11 +118,11 @@ class UserTableMap extends TableMap * e.g. self::$fieldNames[self::TYPE_PHPNAME][0] = 'Id' */ protected static $fieldNames = array ( - self::TYPE_PHPNAME => array('Id', 'MaxKeys', 'Username', 'Password', 'Superuser', ), - self::TYPE_CAMELNAME => array('id', 'maxKeys', 'username', 'password', 'superuser', ), - self::TYPE_COLNAME => array(UserTableMap::COL_ID, UserTableMap::COL_MAX_KEYS, UserTableMap::COL_USERNAME, UserTableMap::COL_PASSWORD, UserTableMap::COL_SUPERUSER, ), - self::TYPE_FIELDNAME => array('id', 'max_keys', 'username', 'password', 'superuser', ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, ) + self::TYPE_PHPNAME => array('Id', 'MaxKeys', 'Username', 'Password', 'Superuser', 'MaxInvites', 'UsedInvites', ), + self::TYPE_CAMELNAME => array('id', 'maxKeys', 'username', 'password', 'superuser', 'maxInvites', 'usedInvites', ), + self::TYPE_COLNAME => array(UserTableMap::COL_ID, UserTableMap::COL_MAX_KEYS, UserTableMap::COL_USERNAME, UserTableMap::COL_PASSWORD, UserTableMap::COL_SUPERUSER, UserTableMap::COL_MAX_INVITES, UserTableMap::COL_USED_INVITES, ), + self::TYPE_FIELDNAME => array('id', 'max_keys', 'username', 'password', 'superuser', 'max_invites', 'used_invites', ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, ) ); /** @@ -122,11 +132,11 @@ class UserTableMap extends TableMap * e.g. self::$fieldKeys[self::TYPE_PHPNAME]['Id'] = 0 */ protected static $fieldKeys = array ( - self::TYPE_PHPNAME => array('Id' => 0, 'MaxKeys' => 1, 'Username' => 2, 'Password' => 3, 'Superuser' => 4, ), - self::TYPE_CAMELNAME => array('id' => 0, 'maxKeys' => 1, 'username' => 2, 'password' => 3, 'superuser' => 4, ), - self::TYPE_COLNAME => array(UserTableMap::COL_ID => 0, UserTableMap::COL_MAX_KEYS => 1, UserTableMap::COL_USERNAME => 2, UserTableMap::COL_PASSWORD => 3, UserTableMap::COL_SUPERUSER => 4, ), - self::TYPE_FIELDNAME => array('id' => 0, 'max_keys' => 1, 'username' => 2, 'password' => 3, 'superuser' => 4, ), - self::TYPE_NUM => array(0, 1, 2, 3, 4, ) + self::TYPE_PHPNAME => array('Id' => 0, 'MaxKeys' => 1, 'Username' => 2, 'Password' => 3, 'Superuser' => 4, 'MaxInvites' => 5, 'UsedInvites' => 6, ), + self::TYPE_CAMELNAME => array('id' => 0, 'maxKeys' => 1, 'username' => 2, 'password' => 3, 'superuser' => 4, 'maxInvites' => 5, 'usedInvites' => 6, ), + self::TYPE_COLNAME => array(UserTableMap::COL_ID => 0, UserTableMap::COL_MAX_KEYS => 1, UserTableMap::COL_USERNAME => 2, UserTableMap::COL_PASSWORD => 3, UserTableMap::COL_SUPERUSER => 4, UserTableMap::COL_MAX_INVITES => 5, UserTableMap::COL_USED_INVITES => 6, ), + self::TYPE_FIELDNAME => array('id' => 0, 'max_keys' => 1, 'username' => 2, 'password' => 3, 'superuser' => 4, 'max_invites' => 5, 'used_invites' => 6, ), + self::TYPE_NUM => array(0, 1, 2, 3, 4, 5, 6, ) ); /** @@ -151,6 +161,8 @@ class UserTableMap extends TableMap $this->addColumn('username', 'Username', 'VARCHAR', false, 64, null); $this->addColumn('password', 'Password', 'VARCHAR', false, 64, null); $this->addColumn('superuser', 'Superuser', 'BOOLEAN', false, null, false); + $this->addColumn('max_invites', 'MaxInvites', 'INTEGER', false, null, 0); + $this->addColumn('used_invites', 'UsedInvites', 'INTEGER', false, null, 0); } // initialize() /** @@ -165,6 +177,13 @@ class UserTableMap extends TableMap 1 => ':id', ), ), null, null, 'Certificates', false); + $this->addRelation('Invite', '\\Eater\\Glim\\Model\\Invite', RelationMap::ONE_TO_MANY, array ( + 0 => + array ( + 0 => ':owner', + 1 => ':id', + ), +), null, null, 'Invites', false); } // buildRelations() /** @@ -313,12 +332,16 @@ class UserTableMap extends TableMap $criteria->addSelectColumn(UserTableMap::COL_USERNAME); $criteria->addSelectColumn(UserTableMap::COL_PASSWORD); $criteria->addSelectColumn(UserTableMap::COL_SUPERUSER); + $criteria->addSelectColumn(UserTableMap::COL_MAX_INVITES); + $criteria->addSelectColumn(UserTableMap::COL_USED_INVITES); } else { $criteria->addSelectColumn($alias . '.id'); $criteria->addSelectColumn($alias . '.max_keys'); $criteria->addSelectColumn($alias . '.username'); $criteria->addSelectColumn($alias . '.password'); $criteria->addSelectColumn($alias . '.superuser'); + $criteria->addSelectColumn($alias . '.max_invites'); + $criteria->addSelectColumn($alias . '.used_invites'); } } From a8a1d48f103c4cea92c814235498c4b498a597d6 Mon Sep 17 00:00:00 2001 From: Corne Oppelaar Date: Tue, 21 Jun 2016 02:11:40 +0200 Subject: [PATCH 6/7] save userId instead of full user --- src/Handler/Login/Action.php | 15 +++++++++++---- src/Handler/Logout.php | 2 +- src/Handler/Session.php | 10 +++++++--- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/Handler/Login/Action.php b/src/Handler/Login/Action.php index 235f44d..00a0006 100644 --- a/src/Handler/Login/Action.php +++ b/src/Handler/Login/Action.php @@ -25,16 +25,23 @@ class Action extends Main $session = $this->get('session'); $segment = $session->getSegment('main'); - $user = $user->login($username, $password); + $loggedUser = $user->login($username, $password); - if ($user === null) { + if ($loggedUser === null) { $segment->setFlash("error", "Login failed, username or password are incorrect"); return $this->redirect('/login'); } - $segment->set('user', $user); - + $segment->set('userId', $loggedUser->getId()); + + $afterLogin = $segment->get('afterLogin'); + $segment->set('afterLogin', null); + + if ($afterLogin !== null) { + return $this->redirect($afterLogin); + } + return $this->redirect('/panel'); } } \ No newline at end of file diff --git a/src/Handler/Logout.php b/src/Handler/Logout.php index 55a6224..728c3f1 100644 --- a/src/Handler/Logout.php +++ b/src/Handler/Logout.php @@ -17,7 +17,7 @@ class Logout extends Main $session = $this->get('session'); $segment = $session->getSegment('main'); - $segment->set('user', null); + $segment->set('userId', null); return $this->redirect('/login'); } diff --git a/src/Handler/Session.php b/src/Handler/Session.php index 4d01348..21d2018 100644 --- a/src/Handler/Session.php +++ b/src/Handler/Session.php @@ -9,7 +9,7 @@ namespace Eater\Glim\Handler; use Aura\Session\Segment; -use Eater\Glim\Model\Base\UserQuery; +use Eater\Glim\Model\UserQuery; use Eater\Glim\Model\User; use Eater\Glim\Service\TwigVars; @@ -18,7 +18,7 @@ class Session extends Main /** * @var bool */ - protected $shouldHaveUser = false; + protected $shouldHaveUser = true; /** * @var bool @@ -60,12 +60,16 @@ class Session extends Main /** @var Segment $segment */ $segment = $session->getSegment('main'); /** @var User $user */ - $user = $segment->get('user'); + $userId = $segment->get('userId'); + + $user = UserQuery::create()->findOneById($userId); + $twigVar->def('user', $user); $this->setUser($user); if ($user === null && ($this->shouldHaveUser || $this->shouldHaveSuperuser)) { + $segment->set('afterLogin', $this->getRequest()->getUri()); return $this->redirect('/login'); } elseif ($this->shouldHaveSuperuser && !$user->getSuperuser()) { return $this->redirect('/panel'); From c53e790fb7fa649692fa343b984474c35fd89749 Mon Sep 17 00:00:00 2001 From: Corne Oppelaar Date: Tue, 21 Jun 2016 02:12:05 +0200 Subject: [PATCH 7/7] add invites! --- bin/create-invite.php | 15 --------- config/routes.yml | 4 +++ src/Handler/Panel/Invites.php | 29 +++++++++++++++++ src/Handler/Panel/Invites/Create.php | 29 +++++++++++++++++ src/Service/User.php | 21 ++++++++++-- views/base_bootstrap.html.twig | 1 + views/panel/invites.html.twig | 48 ++++++++++++++++++++++++++++ 7 files changed, 130 insertions(+), 17 deletions(-) delete mode 100644 bin/create-invite.php create mode 100644 src/Handler/Panel/Invites.php create mode 100644 src/Handler/Panel/Invites/Create.php create mode 100644 views/panel/invites.html.twig diff --git a/bin/create-invite.php b/bin/create-invite.php deleted file mode 100644 index eaa503a..0000000 --- a/bin/create-invite.php +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env php -startTimer(["total"]); -$core->boot($basedir); -echo $core->get('user')->createInvite(); -$core->endTimer(["total"]); - diff --git a/config/routes.yml b/config/routes.yml index 8338904..c521124 100644 --- a/config/routes.yml +++ b/config/routes.yml @@ -32,6 +32,10 @@ routes: post: Panel\Servers\Edit\Action /{fingerprint}/config: Panel\Servers\Config /{fingerprint}/config/{cert}: Panel\Servers\Config + /invites: + get: Panel\Invites + /create: + post: Panel\Invites\Create /server: /register: post: Server\Register \ No newline at end of file diff --git a/src/Handler/Panel/Invites.php b/src/Handler/Panel/Invites.php new file mode 100644 index 0000000..486f6e3 --- /dev/null +++ b/src/Handler/Panel/Invites.php @@ -0,0 +1,29 @@ +getUser(); + + $invites = $user->getInvites(); + + /** @var Segment $segment */ + $segment = $this->get('session')->getSegment('main'); + + return $this->render('panel/invites.html.twig', [ + 'invites' => $invites, + 'error' => $segment->getFlash('error'), + 'used_invites' => $user->getUsedInvites(), + 'max_invites' => $user->getMaxInvites() + ]); + } +} \ No newline at end of file diff --git a/src/Handler/Panel/Invites/Create.php b/src/Handler/Panel/Invites/Create.php new file mode 100644 index 0000000..56ddef4 --- /dev/null +++ b/src/Handler/Panel/Invites/Create.php @@ -0,0 +1,29 @@ +get('user'); + + $userModel = $this->getUser(); + + if ($userModel->getUsedInvites() < $userModel->getMaxInvites() || $userModel->getMaxInvites() === -1) { + $user->createInvite($userModel); + } else { + /** @var Segment $segment */ + $segment = $this->get('session')->getSegment('main'); + $segment->setFlash('error', 'You dont have any invites anymore'); + } + + return $this->redirect('/panel/invites'); + } +} \ No newline at end of file diff --git a/src/Service/User.php b/src/Service/User.php index 6329ac2..c30d697 100644 --- a/src/Service/User.php +++ b/src/Service/User.php @@ -13,7 +13,7 @@ class User extends Main * @param string $invite * @param string $username * @param string $password - * @return Eater\Glim\Model\User + * @return UserModel * @throws \Exception */ public function register($invite, $username, $password) @@ -26,9 +26,20 @@ class User extends Main $this->validateUserParams($username, $password); + $inviteUser = $invite->getUser(); + $user = new UserModel(); $user->setUsername($username); $user->setPassword(\password_hash($password, PASSWORD_DEFAULT)); + + if ($inviteUser === null || $inviteUser->getMaxInvites() === -1) { + $user->setMaxInvites(5); + } elseif ($inviteUser->getMaxInvites() > 0) { + $user->setMaxInvites($inviteUser->getMaxInvites() - 1); + } else { + $user->setMaxInvites(0); + } + $user->save(); $invite->delete(); @@ -66,6 +77,7 @@ class User extends Main $user->setUsername($username); $user->setPassword(\password_hash($password, PASSWORD_DEFAULT)); $user->setSuperuser(true); + $user->setMaxInvites(-1); $user->save(); return $user; @@ -94,14 +106,19 @@ class User extends Main } /** + * @param UserModel $user * @return string */ - public function createInvite() + public function createInvite(UserModel $user) { $invite = new Invite(); $invite->setInvite(bin2hex(openssl_random_pseudo_bytes(20))); + $invite->setUser($user); $invite->save(); + $user->setUsedInvites($user->getUsedInvites() + 1); + $user->save(); + return $invite->getInvite(); } } diff --git a/views/base_bootstrap.html.twig b/views/base_bootstrap.html.twig index 9279db6..e3d2e5a 100644 --- a/views/base_bootstrap.html.twig +++ b/views/base_bootstrap.html.twig @@ -20,6 +20,7 @@
{% if user %} {{ user.username }} + Invites Logout {% else %} Login diff --git a/views/panel/invites.html.twig b/views/panel/invites.html.twig new file mode 100644 index 0000000..675cd18 --- /dev/null +++ b/views/panel/invites.html.twig @@ -0,0 +1,48 @@ +{% extends "base_bootstrap.html.twig" %} + +{% block content %} +
+
+

Invites You used {{ used_invites }} from your {{ max_invites == -1 ? 'infinite' : max_invites }} invites

+
+ {% if error %} +
+ +
+ {% endif %} +
+
+ + + + + + + + {% for invite in invites %} + + + + + {% else %} + + + + {% endfor %} + +
Invite + {% if max_invites > used_invites or max_invites == -1 %} +
+ +
+ {% endif %} +
+ {{ invite.getInvite() }} + + +
You don't have any invites :(
+
+ +{% endblock %} \ No newline at end of file