+
+
+
+
+
+
+
-
-
\ No newline at end of file
diff --git a/app/plugins/bookmarks/views/nav/folderTabs.html b/app/plugins/bookmarks/views/nav/folderTabs.html
index d3e18d9..f73debb 100644
--- a/app/plugins/bookmarks/views/nav/folderTabs.html
+++ b/app/plugins/bookmarks/views/nav/folderTabs.html
@@ -2,5 +2,7 @@
Dashboard
Folders
Import
+
Export
+
Share
{userFolderTabs}
\ No newline at end of file
diff --git a/app/plugins/bookmarks/views/share.html b/app/plugins/bookmarks/views/share.html
new file mode 100644
index 0000000..ea2be1f
--- /dev/null
+++ b/app/plugins/bookmarks/views/share.html
@@ -0,0 +1,19 @@
+
+
+
+
+
+
Any link or folder can be shared. By default, the extensions and app both default to private. On this page, you can quickly see a list of any public links and folders. These "public" items can be shared with anyone who has the link.
+
+ {LOOP}
+
+ {panel}
+
+ {/LOOP}
+ {ALT}
+
+
No public folders found.
+
+ {/ALT}
+
+
\ No newline at end of file
diff --git a/app/plugins/bookmarks/views/shareFolder.html b/app/plugins/bookmarks/views/shareFolder.html
new file mode 100644
index 0000000..25ebcb3
--- /dev/null
+++ b/app/plugins/bookmarks/views/shareFolder.html
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Title: |
+ {title} |
+
+
+ Privacy: |
+ {privacy} |
+
+
+ Color: |
+ {color} |
+
+
+ Created: |
+ {DTC}{createdAt}{/DTC} |
+
+
+ Description |
+
+
+ {description} |
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/plugins/bookmarks/views/shareLink.html b/app/plugins/bookmarks/views/shareLink.html
new file mode 100644
index 0000000..61943d6
--- /dev/null
+++ b/app/plugins/bookmarks/views/shareLink.html
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Title: |
+ {title} |
+
+
+ URL: |
+ {url} |
+
+
+ Type: |
+ {linkType} |
+
+
+ Privacy: |
+ {privacy} |
+
+
+ Color: |
+ {color} |
+
+
+ Created: |
+ {DTC}{createdAt}{/DTC} |
+
+
+ Archived: |
+ {DTC}{archivedAt}{/DTC} |
+
+
+ Hidden: |
+ {DTC}{hiddenAt}{/DTC} |
+
+
+ Last Refreshed: |
+ {DTC}{refreshedAt}{/DTC} |
+
+
+ Description |
+
+
+ {description} |
+
+
+ Icon |
+
+
+ {iconHtml} |
+
+
+ {icon} |
+
+
+ Meta |
+
+
+ {meta} |
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/plugins/members/controllers/member.php b/app/plugins/members/controllers/member.php
index 462c2e0..21b6143 100644
--- a/app/plugins/members/controllers/member.php
+++ b/app/plugins/members/controllers/member.php
@@ -30,42 +30,46 @@ use TheTempusProject\Houdini\Classes\Components;
use TheTempusProject\Classes\Forms;
use TheTempusProject\Bedrock\Functions\Hash;
use TheTempusProject\Canary\Bin\Canary as Debug;
+use Stripe\StripeClient;
class Member extends Controller {
public static $customers;
public static $products;
+ public static $stripe;
+ private static $loaded = false;
public function __construct() {
parent::__construct();
- Template::noIndex();
- $api_key = Config::getValue( 'memberships/stripeSecret' );
- self::$customers = new MembershipCustomers;
- self::$products = new MembershipProducts;
+
+ if ( ! self::$loaded ) {
+ Template::noIndex();
+ self::$customers = new MembershipCustomers;
+ self::$products = new MembershipProducts;
+ $api_key = Config::getValue( 'memberships/stripeSecret' );
+ if ( $api_key == 'sk_xxxxxxxxxxxxxxx' || empty($api_key) ) {
+ Debug::error( "Memberships:__construct No Stripe Key found" );
+ } else {
+ self::$stripe = new StripeClient( $api_key );
+ }
+ self::$loaded = true;
+ }
}
public function index() {
+ $this->confirmAuth();
self::$title = 'Members Area';
- if ( !App::$isMember ) {
- Session::flash( 'error', 'You do not have permission to view this page.' );
- return Redirect::home();
- }
Views::view( 'members.members' );
}
public function managepayment( $id = null ) {
-
-
-
- $api_key = Config::getValue( 'memberships/stripeSecret' );
- $stripe = new \Stripe\StripeClient( $api_key );
-
- $customer = self::$customers->findOrCreate( App::$activeUser->ID );
+ $this->confirmAuth();
+ $customer = self::$customers->findByUserID( App::$activeUser->ID );
if ( empty( $customer ) ) {
Session::flash( 'error', 'You do not have any active payment methods. You can subscribe by going
here' );
return Redirect::to( 'member/manage' );
}
try {
- $session = $stripe->billingPortal->sessions->create([
+ $session = self::$stripe->billingPortal->sessions->create([
'customer' => $customer,
'return_url' => Routes::getAddress() . 'member/manage',
]);
@@ -76,21 +80,14 @@ class Member extends Controller {
return Redirect::to( 'member/manage' );
}
-
-
-
-
-
-
-
header('Location: ' . $session->url);
exit;
}
public function cancelconfirm( $id = null ) {
+ $this->confirmAuth();
$memberships = new Memberships;
$result = $memberships->cancel( $id );
- // dv( $result );
if ( ! empty( $result ) ) {
Session::flash( 'success', 'Your Membership has been paused.' );
Redirect::to( 'member/manage' );
@@ -101,9 +98,9 @@ class Member extends Controller {
}
public function pauseconfirm( $id = null ) {
+ $this->confirmAuth();
$memberships = new Memberships;
$result = $memberships->cancel( $id );
- // dv( $result );
if ( ! empty( $result ) ) {
Session::flash( 'success', 'Your Membership has been paused.' );
Redirect::to( 'member/manage' );
@@ -114,42 +111,64 @@ class Member extends Controller {
}
public function pause( $id = null ) {
+ $this->confirmAuth();
self::$title = 'pause Membership';
Components::set( 'pauseid', $id );
Views::view( 'members.pause' );
}
public function resume( $id = null ) {
+ $this->confirmAuth();
self::$title = 'resume Membership';
Views::view( 'members.resume' );
}
public function cancel( $id = null ) {
+ $this->confirmAuth();
self::$title = 'Cancel Membership';
Components::set( 'cancelid', $id );
Views::view( 'members.cancel' );
}
public function manage( $id = null ) {
+ if ( ! App::$isLoggedIn ) {
+ Session::flash( 'error', 'You do not have permission to access this page.' );
+ return Redirect::home();
+ }
self::$title = 'Manage Membership';
-
+
$menu = Views::simpleView( 'nav.usercp', App::$userCPlinks );
Navigation::activePageSelect( $menu, null, true, true );
-
+
$memberships = new Memberships;
$userMemberships = $memberships->getUserSubs();
-
Views::view( 'members.manage', $userMemberships );
}
-
+
public function upgrade( $id = null ) {
+ if ( ! App::$isLoggedIn ) {
+ Session::flash( 'error', 'You do not have permission to access this page.' );
+ return Redirect::home();
+ }
self::$title = 'Upgrade Membership';
Views::view( 'members.upgrade' );
}
- public function join( $id = null ) {
+ public function join( $plan = 'monthly' ) {
+ if ( ! App::$isLoggedIn ) {
+ Session::flash( 'error', 'You do not have permission to access this page.' );
+ return Redirect::home();
+ }
+ $plan = strtolower( $plan );
+ if ( ! in_array( $plan, ['monthly','yearly'] ) ) {
+ Session::flash( 'error', 'Unknown plan' );
+ return Redirect::to( 'home/index' );
+ }
+
self::$title = 'Join {SIITENAME}!';
- $product = self::$products->findById( $id );
+ $stripePrice = $this->findPrice( $plan );
+
+ $product = self::$products->findByPriceID( $stripePrice );
if ( empty( $product ) ) {
Session::flash( 'success', 'We aren\'t currently accepting new members, please check back soon!' );
return Redirect::home();
@@ -157,92 +176,50 @@ class Member extends Controller {
Views::view( 'members.landing1', $product );
}
- public function getyearly( $id = null ) {
- if ( empty( $id ) ) {
- Issues::add( 'error', 'no id' );
- return $this->index();
- }
- $product = self::$products->findById( $id );
- if ( empty( $product ) ) {
- Issues::add( 'error', 'no product' );
- return $this->index();
+ public function checkout( $plan = 'monthly' ) {
+ if ( ! App::$isLoggedIn ) {
+ Session::flash( 'error', 'You do not have permission to access this page.' );
+ return Redirect::home();
}
$customer = self::$customers->findOrCreate( App::$activeUser->ID );
if ( empty( $customer ) ) {
Issues::add( 'error', 'no customer' );
return $this->index();
}
+ $stripePrice = $this->findPrice( $plan );
- self::$title = 'Purchase';
- $price = $product->stripe_price_yearly;
- $api_key = Config::getValue( 'memberships/stripeSecret' );
- $stripe = new \Stripe\StripeClient( $api_key );
- $session = $stripe->checkout->sessions->create([
+ $session = self::$stripe->checkout->sessions->create([
'payment_method_types' => ['card'],
'customer' => $customer,
'line_items' => [[
- 'price' => $price,
+ 'price' => $stripePrice,
'quantity' => 1,
]],
'mode' => 'subscription',
- 'success_url' => Routes::getAddress() . 'member/paymentcomplete?session_id={CHECKOUT_SESSION_ID}',
- 'cancel_url' => Routes::getAddress() . 'member/paymentcanceled',
+ 'success_url' => Routes::getAddress() . 'member/payment/complete?session_id={CHECKOUT_SESSION_ID}',
+ 'cancel_url' => Routes::getAddress() . 'member/payment/cancel',
]);
header('Location: ' . $session->url);
exit;
}
- public function getmonthly( $id = null ) {
- if ( empty( $id ) ) {
- Issues::add( 'error', 'no id' );
- return $this->index();
- }
- $product = self::$products->findById( $id );
- if ( empty( $product ) ) {
- Issues::add( 'error', 'no product' );
- return $this->index();
- }
- $customer = self::$customers->findOrCreate( App::$activeUser->ID );
- if ( empty( $customer ) ) {
- Issues::add( 'error', 'no customer' );
- return $this->index();
+ public function payment( $type = '' ) {
+ $type = strtolower( $type );
+ if ( ! in_array( $type, ['cancel','complete'] ) ) {
+ Session::flash( 'error', 'Unknown Payment' );
+ return Redirect::to( 'home/index' );
}
- self::$title = 'Purchase';
- $price = $product->stripe_price_monthly;
- $api_key = Config::getValue( 'memberships/stripeSecret' );
- $stripe = new \Stripe\StripeClient( $api_key );
- $session = $stripe->checkout->sessions->create([
- 'payment_method_types' => ['card'],
- 'customer' => $customer,
- 'line_items' => [[
- 'price' => $price,
- 'quantity' => 1,
- ]],
- 'mode' => 'subscription',
- 'success_url' => Routes::getAddress() . 'member/paymentcomplete?session_id={CHECKOUT_SESSION_ID}',
- 'cancel_url' => Routes::getAddress() . 'member/paymentcanceled',
- ]);
- header('Location: ' . $session->url);
- exit;
- }
-
- public function paymentcanceled() {
- self::$title = '(almost) Members Area';
- Views::view( 'members.paymentcanceled' );
- }
+ if ( $type == 'cancel' ) {
+ self::$title = '(almost) Members Area';
+ return Views::view( 'members.paymentcanceled' );
+ }
- public function paymentcomplete() {
self::$title = '(almost) Members Area';
Views::view( 'members.paymentcomplete' );
}
-
-
-
-
-
-
+ // This combines a registration with a checkout
public function signup( $plan = 'monthly' ) {
$plan = strtolower( $plan );
if ( ! in_array( $plan, ['monthly','yearly'] ) ) {
@@ -255,11 +232,10 @@ class Member extends Controller {
Session::flash( 'error', 'Unknown product' );
return Redirect::to( 'home/index' );
}
+
+ $stripePrice = $this->findPrice( $plan );
- $index = 'stripe_price_' . $plan;
$pretty = 'prettyPrice' . ucfirst( $plan );
-
- $stripePrice = $product->$index;
$prettyPrice = $product->$pretty;
self::$title = 'Sign up for {SITENAME} ' . ucfirst( $plan );
@@ -267,17 +243,21 @@ class Member extends Controller {
Components::set( 'planName', ucfirst( $plan ) );
Components::set( 'prettyPrice', $prettyPrice );
Components::set( 'TERMS', Views::simpleView( 'terms' ) );
+
if ( App::$isLoggedIn ) {
- Session::flash( 'notice', 'You are already logged in, were you looking for information on
Upgrading?' );
+ Session::flash( 'notice', 'You are already logged in, you can
subscribe here, or
upgrade here.' );
return Redirect::to( 'home/index' );
}
+
if ( !Input::exists() ) {
return Views::view( 'members.register' );
}
+
if ( ! Forms::check( 'register' ) ) {
Issues::add( 'error', [ 'There was an error with your registration.' => Check::userErrors() ] );
return Views::view( 'members.register' );
}
+
self::$user->create( [
'username' => Input::post( 'username' ),
'password' => Hash::make( Input::post( 'password' ) ),
@@ -297,10 +277,7 @@ class Member extends Controller {
Session::flash( 'error', 'Thank you for registering! Unfortunately, there was an issue communicating with Stripe and we can\'t collect payment right now.' );
return Redirect::to( 'home/index' );
}
-
- $api_key = Config::getValue( 'memberships/stripeSecret' );
- $stripe = new \Stripe\StripeClient( $api_key );
- $session = $stripe->checkout->sessions->create([
+ $session = self::$stripe->checkout->sessions->create([
'payment_method_types' => ['card'],
'customer' => $customer,
'line_items' => [[
@@ -308,10 +285,34 @@ class Member extends Controller {
'quantity' => 1,
]],
'mode' => 'subscription',
- 'success_url' => Routes::getAddress() . 'member/paymentcomplete?session_id={CHECKOUT_SESSION_ID}',
- 'cancel_url' => Routes::getAddress() . 'member/paymentcanceled',
+ 'success_url' => Routes::getAddress() . 'member/payment/complete?session_id={CHECKOUT_SESSION_ID}',
+ 'cancel_url' => Routes::getAddress() . 'member/payment/cancel',
]);
header('Location: ' . $session->url);
exit;
}
+
+ private function findPrice( $plan ) {
+ $plan = strtolower( $plan );
+ if ( ! in_array( $plan, ['monthly','yearly'] ) ) {
+ Session::flash( 'error', 'Unknown plan' );
+ return Redirect::to( 'home/index' );
+ }
+
+ $product = self::$products->mainProduct();
+ if ( empty( $product ) ) {
+ Session::flash( 'error', 'Unknown product' );
+ return Redirect::to( 'home/index' );
+ }
+ $index = 'stripe_price_' . $plan;
+ $stripePrice = $product->$index;
+ return $stripePrice;
+ }
+
+ private function confirmAuth() {
+ if ( ! App::$isLoggedIn || ! App::$isMember ) {
+ Session::flash( 'error', 'You do not have permission to access this page.' );
+ return Redirect::home();
+ }
+ }
}
\ No newline at end of file
diff --git a/app/plugins/members/models/memberships.php b/app/plugins/members/models/memberships.php
index 9c7f853..43e5916 100644
--- a/app/plugins/members/models/memberships.php
+++ b/app/plugins/members/models/memberships.php
@@ -49,8 +49,6 @@ class Memberships extends DatabaseModel {
}
self::$loaded = true;
}
-
-
}
public function filter( $postArray, $params = [] ) {
diff --git a/app/plugins/members/plugin.php b/app/plugins/members/plugin.php
index 11c4f8b..9651282 100644
--- a/app/plugins/members/plugin.php
+++ b/app/plugins/members/plugin.php
@@ -18,6 +18,7 @@ use Stripe\StripeClient;
use TheTempusProject\Bedrock\Classes\Config;
use TheTempusProject\Hermes\Functions\Route as Routes;
use TheTempusProject\Models\Memberships;
+use TheTempusProject\Models\MembershipProducts as Products;
class Members extends Plugin {
public static $stripe;
@@ -42,7 +43,7 @@ class Members extends Plugin {
];
public $admin_links = [
[
- 'text' => '
Memberships',
+ 'text' => '
Memberships',
'url' => [
[
'text' => '
Products',
@@ -60,15 +61,20 @@ class Members extends Plugin {
],
];
public $main_links = [
+ // [
+ // 'text' => 'Members',
+ // 'url' => '{ROOT_URL}member/index',
+ // 'filter' => 'member',
+ // ],
[
- 'text' => 'Members',
- 'url' => '{ROOT_URL}member/index',
- 'filter' => 'member',
+ 'text' => 'Subscribe',
+ 'url' => '{ROOT_URL}member/join',
+ 'filter' => 'nonmember',
],
[
- 'text' => 'Become a Member',
- 'url' => '{ROOT_URL}member/join/1',
- 'filter' => 'nonmember',
+ 'text' => 'Upgrade',
+ 'url' => '{ROOT_URL}member/upgrade',
+ 'filter' => 'upgrade',
],
];
public $resourceMatrix = [
@@ -129,7 +135,13 @@ class Members extends Plugin {
$this->filters[] = [
'name' => 'nonmember',
'find' => '#{NONMEMBER}(.*?){/NONMEMBER}#is',
- 'replace' => ( App::$isLoggedIn && ! App::$isMember ? '$1' : '' ),
+ 'replace' => ( App::$isLoggedIn && App::$isMember == false ? '$1' : '' ),
+ 'enabled' => true,
+ ];
+ $this->filters[] = [
+ 'name' => 'upgrade',
+ 'find' => '#{UPGRADE}(.*?){/UPGRADE}#is',
+ 'replace' => ( App::$isLoggedIn && ( App::$isMember === 'monthly' ) ? '$1' : '' ),
'enabled' => true,
];
$api_key = Config::getValue( 'memberships/stripeSecret' );
@@ -147,14 +159,20 @@ class Members extends Plugin {
}
return false;
}
-
+
public function userHasActiveMembership( $user_id ) {
- self::$memberships = new Memberships;
- $membership = self::$memberships->findActiveByUserID( $user_id );
+ $memberships = new Memberships;
+ $membership = $memberships->findActiveByUserID( $user_id );
if ( empty( $membership ) ) {
return false;
}
- return true;
+
+ $products = new Products;
+ $product = $products->findByPriceID( $membership->subscription_price_id );
+ if ( $product->stripe_price_monthly == $membership->subscription_price_id ) {
+ return 'monthly';
+ }
+ return 'yearly';
}
public static function webhookSetup() {
diff --git a/app/plugins/members/views/landing1.html b/app/plugins/members/views/landing1.html
index 67d8c30..21cb598 100644
--- a/app/plugins/members/views/landing1.html
+++ b/app/plugins/members/views/landing1.html
@@ -1,62 +1,128 @@
-
-
-
-
Organize Your Bookmarks
-
Keep all your bookmarks organized with custom categories and tags.
-
-
-
Import and Export
-
Seamlessly import and export your bookmarks (paid plans).
-
-
-
Accessible Anywhere
-
Your bookmarks are securely stored and accessible from any device.
-
-
-
-
-
-
Pricing
-
-
-
-
-
-
Basic bookmark storage
-
No import/export
-
Completely free
-
Sign Up
-
-
-
-
-
-
-
-
Import/export bookmarks
-
Advanced curation tools
-
{prettyPriceMonthly}/month
-
Sign Up
-
-
-
-
-
-
-
-
Save with annual billing
-
All features included
-
{prettyPriceYearly}/year
-
Sign Up
-
-
-
-
-
-
\ No newline at end of file
+
+
+
Compare plans
+
+
+
+ |
+ Free |
+ Pro |
+ Enterprise |
+
+
+
+
+ Add and Manage Bookmarks |
+ |
+ |
+ |
+
+
+ Extensions for all major browsers |
+ |
+ |
+ |
+
+
+
+
+ Access from any device |
+ |
+ |
+ |
+
+
+ Import/Export Features |
+ |
+ |
+ |
+
+
+ Customizable Dashboards / Pages |
+ |
+ |
+ |
+
+
+ Request/Influence Development |
+ |
+ |
+ |
+
+
+ Early Access |
+ |
+ |
+ |
+
+
+ Cheaper |
+ |
+ |
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
$0/mo
+
+ - Add / Manage your bookmarks
+ - Extensions for all major browsers
+ - Access from any device
+
+
+ Sign-Up for Free
+
+
+
+
+
+
+
+
+
$4.99/month
+
+ - Import/Export Features
+ - Integration with TempusTools App (WIP)
+ - Customizable Dashboards / Pages
+ - Direct control of Feature Development
+ - Early Access to new features
+
+
+ Get started
+
+
+
+
+
+
+
+
+
$19.99/year
+
+ - Its cheaper if you like the product
+
+
+ Get started
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/plugins/members/views/landing2.html b/app/plugins/members/views/landing2.html
index fe76c66..4854f99 100644
--- a/app/plugins/members/views/landing2.html
+++ b/app/plugins/members/views/landing2.html
@@ -20,7 +20,7 @@
{prettyPriceMonthly}/month
All pro features unlocked
-
Get Started
+
Get Started