├── resources ├── views │ ├── .gitkeep │ ├── blade │ │ ├── layouts │ │ │ └── index.html │ │ ├── _variables │ │ │ ├── gv_sep.html │ │ │ ├── gv_comment_ignore.html │ │ │ ├── gv_comment_none.html │ │ │ ├── gv_entries_none.html │ │ │ ├── gv_comment_disabled.html │ │ │ └── gv_comment_expired.html │ │ ├── common │ │ │ ├── index.html │ │ │ ├── _layout.html │ │ │ ├── _footer.html │ │ │ └── _breadcrumb.blade.php │ │ ├── _partials │ │ │ ├── snp_main_nav.blade.php │ │ │ ├── snp_blog_list.blade.php │ │ │ └── snp_blog_list_paginate.blade.php │ │ ├── home │ │ │ └── 404.blade.php │ │ └── blog │ │ │ ├── no-results.blade.php │ │ │ └── search.blade.php │ └── twig │ │ ├── layouts │ │ └── index.html │ │ ├── _variables │ │ ├── gv_sep.html │ │ ├── gv_comment_ignore.html │ │ ├── gv_comment_none.html │ │ ├── gv_entries_none.html │ │ ├── gv_comment_disabled.html │ │ └── gv_comment_expired.html │ │ ├── common │ │ ├── index.html │ │ ├── _layout.html │ │ ├── _footer.html │ │ └── _breadcrumb.twig │ │ ├── _partials │ │ ├── snp_blog_list.twig │ │ ├── snp_main_nav.twig │ │ └── snp_blog_list_paginate.twig │ │ ├── home │ │ └── 404.twig │ │ └── blog │ │ ├── no-results.html │ │ └── search.html └── stubs │ ├── fieldtypes │ ├── rte │ │ ├── field.blade.php │ │ ├── field.twig.php │ │ ├── field.feed.twig.php │ │ ├── field.feed.blade.php │ │ ├── field.html.blade.php │ │ └── field.html.twig.php │ ├── textarea │ │ ├── field.html.blade.php │ │ └── field.html.twig.php │ ├── select.blade.php │ ├── select.twig.php │ ├── date │ │ ├── field.twig.php │ │ ├── field.blade.php │ │ ├── field.html.twig.php │ │ └── field.html.blade.php │ ├── toggle │ │ ├── field.blade.php │ │ ├── field.twig.php │ │ ├── field.html.blade.php │ │ └── field.html.twig.php │ ├── duration │ │ ├── field.twig.php │ │ ├── field.blade.php │ │ ├── field.html.twig.php │ │ └── field.html.blade.php │ ├── multiselect.twig.php │ ├── multiselect.blade.php │ ├── member │ │ ├── field.twig.php │ │ ├── field.blade.php │ │ ├── field.html.blade.php │ │ └── field.html.twig.php │ ├── relationship │ │ ├── field.twig.php │ │ ├── field.blade.php │ │ ├── field.html.blade.php │ │ └── field.html.twig.php │ ├── email_address │ │ ├── field.html.twig.php │ │ └── field.html.blade.php │ ├── select.html.twig.php │ ├── multiselect.html.twig.php │ ├── select.html.blade.php │ ├── multiselect.html.blade.php │ ├── slider │ │ ├── slider.twig.php │ │ ├── slider.blade.php │ │ ├── range_slider.twig.php │ │ └── range_slider.blade.php │ ├── colorpicker │ │ ├── field.blade.php │ │ └── field.twig.php │ ├── pro_variables │ │ ├── field.twig.php │ │ ├── field.html.twig.php │ │ ├── field.blade.php │ │ └── field.html.blade.php │ ├── field.twig.php │ ├── field.blade.php │ ├── field.html.twig.php │ ├── field.html.blade.php │ ├── grid │ │ ├── field.twig.php │ │ └── field.blade.php │ └── file │ │ ├── field.twig.php │ │ ├── field.blade.php │ │ ├── field.html.twig.php │ │ ├── field.html.blade.php │ │ ├── field.feed.twig.php │ │ └── field.feed.blade.php │ └── templates │ ├── member │ └── management │ │ ├── email-password-reset.html.blade.php │ │ ├── email-password-reset.html.twig.php │ │ ├── email-forgot-username.html.blade.php │ │ ├── email-forgot-username.html.twig.php │ │ ├── role-groups.html.blade.php │ │ ├── roles.html.blade.php │ │ ├── role-groups.html.twig.php │ │ ├── roles.html.twig.php │ │ ├── logout.html.blade.php │ │ ├── logout.html.twig.php │ │ ├── edit-avatar.html.blade.php │ │ ├── edit-avatar.html.twig.php │ │ ├── search.html.blade.php │ │ └── search.html.twig.php │ └── channel │ ├── entries │ ├── sitemap.xml.twig.php │ ├── sitemap.xml.blade.php │ ├── feed.feed.twig.php │ ├── feed.feed.blade.php │ ├── index.html.twig.php │ └── index.html.blade.php │ ├── fields │ ├── index.twig.php │ └── index.blade.php │ ├── fieldGroups │ ├── index.twig.php │ └── index.blade.php │ └── channels │ ├── index.twig.php │ └── index.blade.php ├── src ├── .DS_Store ├── Contracts │ ├── Field.php │ ├── ListsGraphType.php │ ├── CompositeFieldtype.php │ ├── ConvertsToGraphQL.php │ └── GeneratesGraphType.php ├── Fieldtypes │ ├── FileGrid.php │ ├── Select.php │ ├── Checkboxes.php │ ├── MultiSelect.php │ ├── SelectableButtons.php │ ├── Presenters │ │ ├── Presenter.php │ │ └── MemberPresenter.php │ ├── Radio.php │ ├── Duration.php │ ├── Number.php │ ├── Modifiers │ │ └── Generic.php │ ├── Rte.php │ ├── Member.php │ └── Relationship.php ├── Models │ ├── Content │ │ ├── Content.php │ │ ├── Structure.php │ │ ├── Display │ │ │ └── LayoutInterface.php │ │ ├── StructureModel.php │ │ ├── FieldGroup.php │ │ ├── FieldData.php │ │ └── VariableColumnGateway.php │ ├── Addon │ │ ├── Grid │ │ │ └── Column.php │ │ ├── Plugin.php │ │ ├── Fieldtype.php │ │ ├── Action.php │ │ ├── Extension.php │ │ └── Module.php │ ├── Template │ │ ├── Snippet.php │ │ ├── GlobalVariable.php │ │ ├── TemplateRoute.php │ │ ├── SpecialtyTemplate.php │ │ └── TemplateGroup.php │ ├── Security │ │ ├── SecurityHash.php │ │ ├── ResetPassword.php │ │ ├── Captcha.php │ │ ├── Throttle.php │ │ └── PasswordLockout.php │ ├── Channel │ │ ├── ChannelFormSettings.php │ │ ├── Scopes │ │ │ ├── HideFuture.php │ │ │ └── HideExpired.php │ │ ├── ChannelEntryAutosave.php │ │ ├── ChannelEntryVersion.php │ │ ├── ChannelFieldGroup.php │ │ └── ChannelLayout.php │ ├── Category │ │ ├── CategoryGroup.php │ │ └── CategoryField.php │ ├── Role │ │ ├── MemberRole.php │ │ ├── RoleGroup.php │ │ ├── RoleSetting.php │ │ └── Role.php │ ├── Session │ │ ├── Session.php │ │ └── RememberMe.php │ ├── Site │ │ ├── Stats.php │ │ └── Column │ │ │ ├── TemplatePreferences.php │ │ │ └── ChannelPreferences.php │ ├── Search │ │ └── SearchLog.php │ ├── Comment │ │ ├── CommentSubscription.php │ │ └── Comment.php │ ├── Permission │ │ └── Permission.php │ ├── EntryManager │ │ └── View.php │ ├── Revision │ │ └── RevisionTracker.php │ ├── Message │ │ ├── Folder.php │ │ ├── ListedMember.php │ │ ├── Attachment.php │ │ ├── Copy.php │ │ └── Message.php │ ├── Consent │ │ ├── ConsentAuditLog.php │ │ ├── Consent.php │ │ ├── ConsentRequest.php │ │ └── ConsentRequestVersion.php │ ├── Member │ │ ├── Online.php │ │ └── MemberField.php │ ├── File │ │ ├── FileDimension.php │ │ ├── Watermark.php │ │ ├── File.php │ │ └── UploadDestination.php │ ├── Config │ │ └── Config.php │ ├── Cookie │ │ └── CookieSetting.php │ └── Status │ │ └── Status.php ├── View │ ├── Exceptions │ │ └── TagNotFoundException.php │ ├── IterableTag.php │ ├── Tags │ │ ├── Channel.php │ │ ├── Member │ │ │ ├── LoginForm.php │ │ │ ├── LogoutForm.php │ │ │ ├── ForgotPasswordForm.php │ │ │ ├── ForgotUsernameForm.php │ │ │ ├── MemberSearch.php │ │ │ ├── EditAvatar.php │ │ │ ├── EditProfile.php │ │ │ ├── RegistrationForm.php │ │ │ ├── Memberlist.php │ │ │ └── CustomProfileData.php │ │ └── Channel │ │ │ └── Form.php │ ├── AddonTag.php │ ├── MissingTag.php │ ├── Extensions │ │ └── TwigVite.php │ ├── Tag.php │ └── TagProxy.php ├── Model.php ├── Facades │ ├── GraphQL.php │ └── Coilpack.php ├── Support │ └── Arguments │ │ ├── EmptyTerm.php │ │ ├── Argument.php │ │ ├── TermFactory.php │ │ ├── SearchArgument.php │ │ ├── NumericTerm.php │ │ └── ListArgument.php ├── Controllers │ ├── AdminController.php │ ├── FallbackController.php │ └── Cp │ │ └── Coilpack.php ├── Traits │ ├── InteractsWithAddon.php │ ├── ForwardsAttributes.php │ └── CanAccessRestrictedClass.php ├── Api │ └── Graph │ │ ├── Queries │ │ ├── MembersQuery.php │ │ ├── VariablesQuery.php │ │ ├── MemberCurrentQuery.php │ │ ├── CategoryQuery.php │ │ └── ChannelEntryQuery.php │ │ ├── Support │ │ ├── GeneratedType.php │ │ ├── GeneratedInputType.php │ │ └── GeneratedUnionType.php │ │ ├── Schema.php │ │ ├── Middleware │ │ └── ResolvePage.php │ │ └── Types │ │ ├── KeyedValue.php │ │ ├── Status.php │ │ ├── NavItem.php │ │ └── Channel.php ├── NavOutput.php ├── Events │ └── HookTriggered.php ├── Dependency │ ├── NavigationSidebar.php │ ├── Container.php │ └── StubFactory.php ├── Bootstrap │ ├── ConfigureStorageDisk.php │ ├── SetupCacheManager.php │ └── LoadAddonFiles.php ├── Casts │ ├── Serialize.php │ ├── Base64Serialized.php │ ├── UnixTimestamp.php │ └── BooleanString.php ├── Middleware │ ├── EncryptCookies.php │ ├── MemberWithRole.php │ └── MemberWithPermission.php ├── FieldtypeOutput.php ├── Commands │ └── GraphQLCommand.php └── Routing │ └── CoilpackRoutes.php ├── addon ├── addon.setup.php └── views │ ├── overview.php │ └── graphql.php ├── routes └── web.php ├── README.md └── LICENSE.md /resources/views/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/views/blade/layouts/index.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/views/twig/layouts/index.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/views/blade/_variables/gv_sep.html: -------------------------------------------------------------------------------- 1 |  /  -------------------------------------------------------------------------------- /resources/views/twig/_variables/gv_sep.html: -------------------------------------------------------------------------------- 1 |  /  -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/rte/field.blade.php: -------------------------------------------------------------------------------- 1 | {{ }} -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/rte/field.twig.php: -------------------------------------------------------------------------------- 1 | {{ }} -------------------------------------------------------------------------------- /resources/views/blade/_variables/gv_comment_ignore.html: -------------------------------------------------------------------------------- 1 | You are ignoring -------------------------------------------------------------------------------- /resources/views/twig/_variables/gv_comment_ignore.html: -------------------------------------------------------------------------------- 1 | You are ignoring -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/textarea/field.html.blade.php: -------------------------------------------------------------------------------- 1 | {!! !!} -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/textarea/field.html.twig.php: -------------------------------------------------------------------------------- 1 | {{ | raw }} -------------------------------------------------------------------------------- /src/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpressionEngine/Coilpack/HEAD/src/.DS_Store -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/select.blade.php: -------------------------------------------------------------------------------- 1 | {{ ->label }}: {{ }} -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/select.twig.php: -------------------------------------------------------------------------------- 1 | {{ .label }}: {{ }} -------------------------------------------------------------------------------- /resources/views/blade/_variables/gv_comment_none.html: -------------------------------------------------------------------------------- 1 | There are no comments on this entry. -------------------------------------------------------------------------------- /resources/views/blade/_variables/gv_entries_none.html: -------------------------------------------------------------------------------- 1 | There are no entries in this channel. -------------------------------------------------------------------------------- /resources/views/twig/_variables/gv_comment_none.html: -------------------------------------------------------------------------------- 1 | There are no comments on this entry. -------------------------------------------------------------------------------- /resources/views/twig/_variables/gv_entries_none.html: -------------------------------------------------------------------------------- 1 | There are no entries in this channel. -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/date/field.twig.php: -------------------------------------------------------------------------------- 1 | {{ .parameters({format: "%F %d %Y"}) }} -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/rte/field.feed.twig.php: -------------------------------------------------------------------------------- 1 | {{ .parameters({text_only: "yes"}) }} -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/toggle/field.blade.php: -------------------------------------------------------------------------------- 1 | @if( == '1')On/Yes@elseOff/No@endif -------------------------------------------------------------------------------- /resources/views/blade/_variables/gv_comment_disabled.html: -------------------------------------------------------------------------------- 1 | Commenting for this entry is disabled. -------------------------------------------------------------------------------- /resources/views/blade/_variables/gv_comment_expired.html: -------------------------------------------------------------------------------- 1 | Commenting for this entry has expired. -------------------------------------------------------------------------------- /resources/views/twig/_variables/gv_comment_disabled.html: -------------------------------------------------------------------------------- 1 | Commenting for this entry is disabled. -------------------------------------------------------------------------------- /resources/views/twig/_variables/gv_comment_expired.html: -------------------------------------------------------------------------------- 1 | Commenting for this entry has expired. -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/date/field.blade.php: -------------------------------------------------------------------------------- 1 | {{ ->parameters(['format' => "%F %d %Y"]) }} -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/duration/field.twig.php: -------------------------------------------------------------------------------- 1 | {{ .parameters({format: "%h hrs, %m min"}) }} -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/rte/field.feed.blade.php: -------------------------------------------------------------------------------- 1 | {{ ->parameters(['text_only' => "yes"]) }} -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/toggle/field.twig.php: -------------------------------------------------------------------------------- 1 | {% if == '1' %}On/Yes{% else %}Off/No{% endif %} -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/duration/field.blade.php: -------------------------------------------------------------------------------- 1 | {{ ->parameters(['format' => "%h hrs, %m min"]) }} -------------------------------------------------------------------------------- /src/Contracts/Field.php: -------------------------------------------------------------------------------- 1 | .selected %} 2 | {{ label }}: {{ value }} 3 | {% endfor %} -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/toggle/field.html.blade.php: -------------------------------------------------------------------------------- 1 | @if( == '1')Yes@elseNo@endif -------------------------------------------------------------------------------- /src/Fieldtypes/Checkboxes.php: -------------------------------------------------------------------------------- 1 | ->selected as $value => $label) 2 | {{ $label }}: {{ $value }} 3 | @endforeach -------------------------------------------------------------------------------- /resources/views/blade/common/index.html: -------------------------------------------------------------------------------- 1 | {!-- nothing to see here, so we redirect the users if they land on http://example.com/common/ --} 2 | {redirect='/'} -------------------------------------------------------------------------------- /resources/views/twig/common/index.html: -------------------------------------------------------------------------------- 1 | {!-- nothing to see here, so we redirect the users if they land on http://example.com/common/ --} 2 | {redirect='/'} -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/toggle/field.html.twig.php: -------------------------------------------------------------------------------- 1 | {% if == '1' %}Yes{% else %}No{% endif %} -------------------------------------------------------------------------------- /src/Fieldtypes/SelectableButtons.php: -------------------------------------------------------------------------------- 1 | }}">{{ .parameters({format: "%h hrs, %m min"}) }} -------------------------------------------------------------------------------- /src/Models/Content/Content.php: -------------------------------------------------------------------------------- 1 | }}">{{ ->parameters(['format' => "%h hrs, %m min"]) }} -------------------------------------------------------------------------------- /src/View/Exceptions/TagNotFoundException.php: -------------------------------------------------------------------------------- 1 | .parameters({format: '%c'}) }}">{{ .parameters({format: "%F %d %Y"}) }} -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/member/field.twig.php: -------------------------------------------------------------------------------- 1 | {% for related_member in %} 2 | {{ related_member.screen_name }} - {{ related_member.username }} 3 | {% endfor %} -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/relationship/field.twig.php: -------------------------------------------------------------------------------- 1 | {% for related_entry in %} 2 | {{ related_entry.title }} - {{ related_entry.url_title }} 3 | {% endfor %} -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/member/field.blade.php: -------------------------------------------------------------------------------- 1 | @foreach( as $related_member) 2 | {{ $related_member->screen_name }} - {{ $related_member->username }} 3 | @endforeach -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/relationship/field.blade.php: -------------------------------------------------------------------------------- 1 | @foreach( as $related_entry) 2 | {{ $related_entry->title }} - {{ $related_entry->url_title }} 3 | @endforeach -------------------------------------------------------------------------------- /src/Models/Content/Structure.php: -------------------------------------------------------------------------------- 1 | ->parameters(['format' => '%c']) }}">{{ ->parameters(['format' => "%F %d %Y"]) }} -------------------------------------------------------------------------------- /src/Contracts/ConvertsToGraphQL.php: -------------------------------------------------------------------------------- 1 | {{ .mailto({title:"Send e-mail", subject:"Question", encode:false}) | raw }} / {{ }} -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/select.html.twig.php: -------------------------------------------------------------------------------- 1 | {{ .label }}: {{ }} / {{ .value }} -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/email_address/field.html.blade.php: -------------------------------------------------------------------------------- 1 | {!! ->mailto(['title' => "Send e-mail", 'subject' => "Question", 'encode' => false]) !!} / {{ }} -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/multiselect.html.twig.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/select.html.blade.php: -------------------------------------------------------------------------------- 1 | {{ ->label }}: {{ }} / {{ ->value }} -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/multiselect.html.blade.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/slider/slider.twig.php: -------------------------------------------------------------------------------- 1 | Between {{ .min }} and {{ .max }} the selected value is {{ .prefix }} {{ }} {{ .suffix }} -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/slider/slider.blade.php: -------------------------------------------------------------------------------- 1 | Between {{ ->min }} and {{ ->max }} the selected value is {{ ->prefix }} {{ }} {{ ->suffix }} -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/slider/range_slider.twig.php: -------------------------------------------------------------------------------- 1 | Selected range is {{ .prefix }}{{ .from }}{{ .suffix }} — {{ .prefix }}{{ .to }}{{ .suffix }} -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/slider/range_slider.blade.php: -------------------------------------------------------------------------------- 1 | Selected range is {{ ->prefix }}{{ ->from }}{{ ->suffix }} — {{ ->prefix }}{{ ->to }}{{ ->suffix }} -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/colorpicker/field.blade.php: -------------------------------------------------------------------------------- 1 |
2 |

3 | This text will contrast with the background so it's always legible-> 4 |

5 |
-------------------------------------------------------------------------------- /resources/stubs/fieldtypes/colorpicker/field.twig.php: -------------------------------------------------------------------------------- 1 |
2 |

3 | This text will contrast with the background so it's always legible. 4 |

5 |
-------------------------------------------------------------------------------- /src/Models/Content/Display/LayoutInterface.php: -------------------------------------------------------------------------------- 1 | ->has_excerpt == 'y') 2 |
3 | {!! ->excerpt !!} 4 | {!! ->extended !!} 5 |
6 | @else 7 | {!! !!} 8 | @endif -------------------------------------------------------------------------------- /src/Contracts/GeneratesGraphType.php: -------------------------------------------------------------------------------- 1 | 2 | @foreach( as $related_member) 3 |
  • last) class="last" @endif>username) }}">{{ $related_member->screen_name }}
  • 4 | @endforeach 5 | -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/member/field.html.twig.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/pro_variables/field.twig.php: -------------------------------------------------------------------------------- 1 | 2 | {{ exp.pro_variables.single({var: ""}) }} 3 | 4 | {# Not Yet Supported 5 | {{ exp.pro_variables.pair({var: ""}) }} #} 6 | -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/relationship/field.html.blade.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/relationship/field.html.twig.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/Fieldtypes/Presenters/Presenter.php: -------------------------------------------------------------------------------- 1 | 2 | {{ exp.pro_variables.single({var: ""}) }} 3 | 4 | {# Not Yet Supported 5 | {{ exp.pro_variables.pair({var: ""}) }} #} 6 | -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/rte/field.html.twig.php: -------------------------------------------------------------------------------- 1 | {% if .has_excerpt == 'y' %} 2 |
    3 | {{ .excerpt | raw }} 4 | {{ .extended | raw }} 5 |
    6 | {% else %} 7 | {{ | raw }} 8 | {% endif %} -------------------------------------------------------------------------------- /src/Model.php: -------------------------------------------------------------------------------- 1 | 2 | {{ $exp->pro_variables->single(['var' => ""]) }} 3 | 4 | {{-- Not Yet Supported 5 | {{ $exp->pro_variables->pair(['var': ""]) }} --}} 6 | -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/pro_variables/field.html.blade.php: -------------------------------------------------------------------------------- 1 | 2 | {{ $exp->pro_variables->single(['var' => ""]) }} 3 | 4 | {{-- Not Yet Supported 5 | {{ $exp->pro_variables->pair(['var' => ""]) }} --}} 6 | -------------------------------------------------------------------------------- /src/View/IterableTag.php: -------------------------------------------------------------------------------- 1 | run(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Models/Content/FieldGroup.php: -------------------------------------------------------------------------------- 1 | belongsTo(Field::class, 'field_id'); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Support/Arguments/EmptyTerm.php: -------------------------------------------------------------------------------- 1 | whereNull($column, $boolean, $not); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Controllers/AdminController.php: -------------------------------------------------------------------------------- 1 | admin() 11 | ->bootstrap(app()) 12 | ->runGlobal(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /resources/stubs/templates/member/management/email-forgot-username.html.blade.php: -------------------------------------------------------------------------------- 1 | Hello {name}, 2 | 3 | We received a request to remind you of your username. Here it is: 4 | 5 | Username: {username} 6 | 7 | If you did not request this information, please contact our support team immediately to ensure the security of your account. 8 | 9 | Thank you, 10 | 11 | {site_name} 12 | {site_url} 13 | -------------------------------------------------------------------------------- /resources/stubs/templates/member/management/email-forgot-username.html.twig.php: -------------------------------------------------------------------------------- 1 | Hello {name}, 2 | 3 | We received a request to remind you of your username. Here it is: 4 | 5 | Username: {username} 6 | 7 | If you did not request this information, please contact our support team immediately to ensure the security of your account. 8 | 9 | Thank you, 10 | 11 | {site_name} 12 | {site_url} 13 | -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/field.twig.php: -------------------------------------------------------------------------------- 1 | 2 | {% for row in %} 3 | {# This field is built to be used as tag pair #} 4 | {# But we could not determine the possible variables to use inside tag pair #} 5 | {# Please refer to the documentation link above #} 6 | {{ row }} 7 | {% endfor %} 8 | 9 | {{ }} 10 | -------------------------------------------------------------------------------- /src/Fieldtypes/Radio.php: -------------------------------------------------------------------------------- 1 | 2 | @foreach( as $row) 3 | {{-- This field is built to be used as tag pair --}} 4 | {{-- But we could not determine the possible variables to use inside tag pair --}} 5 | {{-- Please refer to the documentation link above --}} 6 | {{ $row }} 7 | @endforeach 8 | 9 | {{ }} 10 | -------------------------------------------------------------------------------- /src/Support/Arguments/Argument.php: -------------------------------------------------------------------------------- 1 | value = $value; 12 | } 13 | 14 | public function __get($key) 15 | { 16 | if (isset($this->$key)) { 17 | return $this->$key; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Models/Addon/Plugin.php: -------------------------------------------------------------------------------- 1 | \Expressionengine\Coilpack\Casts\BooleanString::class, 18 | ]; 19 | } 20 | -------------------------------------------------------------------------------- /src/View/AddonTag.php: -------------------------------------------------------------------------------- 1 | signature); 14 | $this->addon = $pieces[0]; 15 | $this->method = $pieces[1]; 16 | $this->instance = ee('Addon')->get($this->addon); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Models/Template/Snippet.php: -------------------------------------------------------------------------------- 1 | [ 18 | 'type' => 'BelongsTo', 19 | ], 20 | ]; 21 | } 22 | -------------------------------------------------------------------------------- /resources/stubs/templates/channel/entries/sitemap.xml.twig.php: -------------------------------------------------------------------------------- 1 | '."\n"?> 2 | 3 | 4 | {% for entry in exp.channel.entries({channel: ""}) %} 5 | 6 | {{ exp.path('/entry', entry.url_title) }} 7 | {{ entry.edit_date.format('Y-m-d') }} 8 | 9 | {% endfor %} 10 | 11 | -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/field.html.twig.php: -------------------------------------------------------------------------------- 1 | 2 |
    3 | {% for row in %} 4 | {# This field is built to be used as tag pair #} 5 | {# But we could not determine the possible variables to use inside tag pair #} 6 | {# Please refer to the documentation link above #} 7 | {{ row }} 8 | {% endfor %} 9 |
    10 | 11 |
    12 | {{ }} 13 |
    14 | -------------------------------------------------------------------------------- /resources/stubs/templates/channel/entries/sitemap.xml.blade.php: -------------------------------------------------------------------------------- 1 | '."\n"?> 2 | 3 | 4 | @foreach($exp->channel->entries(['channel' => ""]) as $entry) 5 | 6 | {{ $exp->path('/entry', $entry->url_title) }} 7 | {{ $entry->edit_date->format('Y-m-d') }} 8 | 9 | @endforeach 10 | 11 | -------------------------------------------------------------------------------- /addon/addon.setup.php: -------------------------------------------------------------------------------- 1 | 'Packet Tide, LLC', 5 | 'author_url' => 'https://packettide.com/', 6 | 'name' => 'Coilpack', 7 | 'description' => 'Supercharge ExpressionEngine with more power, features, and flexibility!', 8 | 'version' => \Composer\InstalledVersions::getPrettyVersion('expressionengine/coilpack'), 9 | 'namespace' => 'ExpressionEngine\Addons\Coilpack', 10 | 'settings_exist' => false, 11 | 'built_in' => true, 12 | ]; 13 | -------------------------------------------------------------------------------- /src/Models/Security/SecurityHash.php: -------------------------------------------------------------------------------- 1 | [ 18 | 'type' => 'belongsTo', 19 | ], 20 | ]; 21 | } 22 | -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/field.html.blade.php: -------------------------------------------------------------------------------- 1 | 2 |
    3 | @foreach( as $row) 4 | {{-- This field is built to be used as tag pair --}} 5 | {{-- But we could not determine the possible variables to use inside tag pair --}} 6 | {{-- Please refer to the documentation link above --}} 7 | {{ $row }} 8 | @endforeach 9 |
    10 | 11 |
    12 | {{ }} 13 |
    14 | -------------------------------------------------------------------------------- /src/View/MissingTag.php: -------------------------------------------------------------------------------- 1 | tags = $tags; 10 | } 11 | 12 | public function __get($key) 13 | { 14 | return $this; 15 | } 16 | 17 | public function __call($method, $args) 18 | { 19 | return $this; 20 | } 21 | 22 | public function __isset($key) 23 | { 24 | return true; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /resources/views/twig/_partials/snp_blog_list.twig: -------------------------------------------------------------------------------- 1 |
    2 | {# title #} 3 |

    {{ entry.title }}

    4 |

    on: {{ entry.entry_date.format('n/j/Y') }}, by: {{ entry.author.screen_name }}, {{ entry.comment_total }} {{ str_plural('comment', entry.comment_total) }}

    5 |
    -------------------------------------------------------------------------------- /src/Models/Addon/Fieldtype.php: -------------------------------------------------------------------------------- 1 | \Expressionengine\Coilpack\Casts\BooleanString::class, 18 | 'settings' => 'base64Serialized', 19 | ]; 20 | } 21 | -------------------------------------------------------------------------------- /resources/views/blade/_partials/snp_main_nav.blade.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/Models/Channel/ChannelFormSettings.php: -------------------------------------------------------------------------------- 1 | belongsTo(Channel::class, 'channel_id'); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /resources/views/twig/_partials/snp_main_nav.twig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/Support/Arguments/TermFactory.php: -------------------------------------------------------------------------------- 1 | belongsTo(Member::class, 'member_id'); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Traits/InteractsWithAddon.php: -------------------------------------------------------------------------------- 1 | get($addon)->getFrontendClass(); 10 | 11 | return new $addonClass; 12 | } 13 | 14 | public function getAddonModuleInstance($addon) 15 | { 16 | $module = '\\'.ltrim(\ee('Addon')->get($addon)->getModuleClass(), '\\'); 17 | 18 | return new $module; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /resources/stubs/templates/channel/fields/index.twig.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {# Field: #} 5 | {# Fieldtype: #} 6 | {# Docs: #} 7 | 8 | 9 | 10 | embed($field['stub'], $field);?> 11 | 12 | 13 | {# End field: #} 14 | 15 | -------------------------------------------------------------------------------- /resources/views/blade/home/404.blade.php: -------------------------------------------------------------------------------- 1 | @extends ('coilpack::blade/layouts/_html-wrapper') 2 | 3 | @section('contents') 4 |
    5 |
    6 |
    7 | Doing Business! 8 |
    9 |
    10 |
    11 |

    404 — Page Not Found

    12 |

    Super sorry about that, but the page you are trying to access is nowhere to be found.

    13 |

    We searched our whole desk.

    14 |
    15 |
    16 | @endsection -------------------------------------------------------------------------------- /resources/views/twig/_partials/snp_blog_list_paginate.twig: -------------------------------------------------------------------------------- 1 | {# pagination #} 2 | {% if entries.hasPages() %} 3 |
    4 | 19 |
    20 | {% endif %} 21 | -------------------------------------------------------------------------------- /resources/views/twig/home/404.twig: -------------------------------------------------------------------------------- 1 | {% extends 'coilpack::twig/layouts/_html-wrapper' %} 2 | 3 | {% block 'contents' %} 4 |
    5 |
    6 |
    7 | Doing Business! 8 |
    9 |
    10 |
    11 |

    404 — Page Not Found

    12 |

    Super sorry about that, but the page you are trying to access is nowhere to be found.

    13 |

    We searched our whole desk.

    14 |
    15 |
    16 | {% endblock %} -------------------------------------------------------------------------------- /src/Models/Template/GlobalVariable.php: -------------------------------------------------------------------------------- 1 | [ 20 | 'type' => 'belongsTo', 21 | ], 22 | ]; 23 | } 24 | -------------------------------------------------------------------------------- /resources/views/blade/common/_layout.html: -------------------------------------------------------------------------------- 1 | {!-- template vars --} 2 | {!-- used double quotes in this one file, as og_url required it :( --} 3 | {preload_replace:t_inc="common/"} 4 | 5 | {!-- embed the header --} 6 | {embed="{t_inc}_header" 7 | title="{layout:title}" 8 | desc="{layout:desc}" 9 | {if layout:ogtitle} 10 | ogtitle="{layout:ogtitle}" 11 | og_url="{layout:og_url}" 12 | og_description="{layout:og_description}" 13 | {/if} 14 | } 15 | 16 | {!-- cALL the content --} 17 | {layout:contents} 18 | 19 | {!-- embed the footer --} 20 | {embed="{t_inc}_footer"} -------------------------------------------------------------------------------- /resources/views/twig/common/_layout.html: -------------------------------------------------------------------------------- 1 | {!-- template vars --} 2 | {!-- used double quotes in this one file, as og_url required it :( --} 3 | {preload_replace:t_inc="common/"} 4 | 5 | {!-- embed the header --} 6 | {embed="{t_inc}_header" 7 | title="{layout:title}" 8 | desc="{layout:desc}" 9 | {if layout:ogtitle} 10 | ogtitle="{layout:ogtitle}" 11 | og_url="{layout:og_url}" 12 | og_description="{layout:og_description}" 13 | {/if} 14 | } 15 | 16 | {!-- cALL the content --} 17 | {layout:contents} 18 | 19 | {!-- embed the footer --} 20 | {embed="{t_inc}_footer"} -------------------------------------------------------------------------------- /resources/stubs/templates/channel/fields/index.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{-- Field: --}} 5 | {{-- Fieldtype: --}} 6 | {{-- Docs: --}} 7 | 8 | {$field['field_name']}"; ?> 9 | 10 | embed($field['stub'], $field);?> 11 | 12 | 13 | {{-- End field: --}} 14 | 15 | -------------------------------------------------------------------------------- /src/Api/Graph/Queries/MembersQuery.php: -------------------------------------------------------------------------------- 1 | 'members', 13 | ]; 14 | 15 | public function type(): Type 16 | { 17 | return GraphQL::type('Member'); 18 | } 19 | 20 | public function args(): array 21 | { 22 | return []; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Models/Security/Captcha.php: -------------------------------------------------------------------------------- 1 | 'ip_address', 18 | ]; 19 | 20 | protected $captcha_id; 21 | 22 | protected $date; 23 | 24 | protected $ip_address; 25 | 26 | protected $word; 27 | } 28 | -------------------------------------------------------------------------------- /src/Models/Channel/Scopes/HideFuture.php: -------------------------------------------------------------------------------- 1 | where('entry_date', '<=', now()->timestamp); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /resources/stubs/templates/member/management/role-groups.html.blade.php: -------------------------------------------------------------------------------- 1 | @extends('ee::._layout') 2 | @section('title', 'Role Groups') 3 | 4 | @section('contents') 5 | 6 | View Template 7 | 8 |
    9 |

    Your member role groups:

    10 | 15 |
    16 | 17 | @endsection -------------------------------------------------------------------------------- /resources/stubs/templates/member/management/roles.html.blade.php: -------------------------------------------------------------------------------- 1 | @extends('ee::._layout') 2 | @section('title', 'Roles') 3 | 4 | @section('contents') 5 | 6 | View Template 7 | 8 |
    9 |

    Your member roles:

    10 | 15 |
    16 | 17 | @endsection -------------------------------------------------------------------------------- /resources/views/blade/_partials/snp_blog_list.blade.php: -------------------------------------------------------------------------------- 1 |
    2 | {{-- title --}} 3 | {{-- @dd($entry) --}} 4 |

    url_title") }}">{{ $entry->title }}

    5 |

    on: {{ $entry->entry_date->format('n/j/Y') }} {{-- ->format('n/j/Y') }} --}}, by: author_id}") }}">{{ $entry->author->screen_name }}, url_title#comments") }}">{{ $entry->comment_total }} {{ Str::plural('comment', $entry->comment_total) }}

    6 |
    -------------------------------------------------------------------------------- /src/Models/Category/CategoryGroup.php: -------------------------------------------------------------------------------- 1 | hasMany(Category::class); 19 | } 20 | 21 | public function fields() 22 | { 23 | return $this->hasMany(CategoryField::class); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /resources/stubs/templates/member/management/role-groups.html.twig.php: -------------------------------------------------------------------------------- 1 | {% extends 'ee::/_layout' %} 2 | {% block title %}Role Groups{% endblock %} 3 | 4 | {% block contents %} 5 | 6 | View Template 7 | 8 |
    9 |

    Your member role groups:

    10 | 15 |
    16 | 17 | {% endblock %} -------------------------------------------------------------------------------- /resources/views/blade/_partials/snp_blog_list_paginate.blade.php: -------------------------------------------------------------------------------- 1 | {{-- pagination --}} 2 | @if($entries->hasPages()) 3 |
    4 | 13 |
    14 | @endif -------------------------------------------------------------------------------- /src/NavOutput.php: -------------------------------------------------------------------------------- 1 | array : $entries; 11 | 12 | foreach ($entries as $item) { 13 | $output .= $callback( 14 | $item, 15 | $this->render($callback, $item['children']), 16 | $item['depth'] 17 | ); 18 | } 19 | 20 | return $output; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /resources/stubs/templates/member/management/roles.html.twig.php: -------------------------------------------------------------------------------- 1 | {% extends 'ee::/_layout' %} 2 | {% block title %}Roles{% endblock %} 3 | 4 | {% block contents %} 5 | 6 | View Template 7 | 8 |
    9 |

    Your member roles:

    10 | 15 |
    16 | 17 | {% endblock %} -------------------------------------------------------------------------------- /src/Api/Graph/Support/GeneratedType.php: -------------------------------------------------------------------------------- 1 | attributes = $attributes; 12 | } 13 | 14 | public function fields(): array 15 | { 16 | if (is_callable($this->attributes['fields'])) { 17 | return $this->attributes['fields'](); 18 | } 19 | 20 | return $this->attributes['fields'] ?? []; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Fieldtypes/Duration.php: -------------------------------------------------------------------------------- 1 | 'format', 15 | 'type' => 'string', 16 | 'description' => 'Specify the format for this duration. Ex: %h hrs, %m min', 17 | ]), 18 | ]; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Api/Graph/Support/GeneratedInputType.php: -------------------------------------------------------------------------------- 1 | attributes = $attributes; 12 | } 13 | 14 | public function fields(): array 15 | { 16 | if (is_callable($this->attributes['fields'])) { 17 | return $this->attributes['fields'](); 18 | } 19 | 20 | return $this->attributes['fields'] ?? []; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Api/Graph/Support/GeneratedUnionType.php: -------------------------------------------------------------------------------- 1 | attributes = $attributes; 12 | } 13 | 14 | public function types(): array 15 | { 16 | if (is_callable($this->attributes['types'])) { 17 | return $this->attributes['types'](); 18 | } 19 | 20 | return $this->attributes['types'] ?? []; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Fieldtypes/Number.php: -------------------------------------------------------------------------------- 1 | 'decimal_places', 15 | 'type' => 'integer', 16 | 'description' => 'The number of decimal digits to show after the number', 17 | ]), 18 | ]; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/View/Extensions/TwigVite.php: -------------------------------------------------------------------------------- 1 | __invoke($resource), 'UTF-8'); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Models/Security/Throttle.php: -------------------------------------------------------------------------------- 1 | 'ip_address', 18 | ]; 19 | 20 | protected $throttle_id; 21 | 22 | protected $ip_address; 23 | 24 | protected $last_activity; 25 | 26 | protected $hits; 27 | 28 | protected $locked_out; 29 | } 30 | -------------------------------------------------------------------------------- /src/Api/Graph/Schema.php: -------------------------------------------------------------------------------- 1 | GraphQL::getQueries(), 14 | 'mutation' => [ 15 | 16 | ], 17 | 'middleware' => GraphQL::getMiddleware(), 18 | 'method' => ['GET', 'POST'], 19 | 'types' => GraphQL::getTypes(), 20 | ]; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Models/Role/MemberRole.php: -------------------------------------------------------------------------------- 1 | hasMany(Member::class, 'member_id'); 20 | } 21 | 22 | public function roles() 23 | { 24 | return $this->hasMany(Role::class, 'role_id'); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Models/Session/Session.php: -------------------------------------------------------------------------------- 1 | \Expressionengine\Coilpack\Casts\BooleanString::class, 19 | ]; 20 | 21 | public function member() 22 | { 23 | return $this->belongsTo(Member::class, 'member_id'); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Fieldtypes/Presenters/MemberPresenter.php: -------------------------------------------------------------------------------- 1 | buildRelationshipQuery($content, new Member); 16 | 17 | return $query->get(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Api/Graph/Middleware/ResolvePage.php: -------------------------------------------------------------------------------- 1 | ._layout') 2 | @section('title', 'Logout') 3 | 4 | @section('contents') 5 | 6 | @if($global->logged_out) 7 | {{ $exp->redirect("/login") }} 8 | @endif 9 | 10 | View Template 11 | 12 | @php $form = $exp->member->logout_form(['return' => "/login"]) @endphp 13 | {!! $form->open() !!} 14 | 15 | {!! $form->close() !!} 16 | 17 | @endsection -------------------------------------------------------------------------------- /src/Models/Security/PasswordLockout.php: -------------------------------------------------------------------------------- 1 | 'ip_address', 18 | ]; 19 | 20 | protected $lockout_id; 21 | 22 | protected $login_date; 23 | 24 | protected $ip_address; 25 | 26 | protected $user_agent; 27 | 28 | protected $username; 29 | } 30 | -------------------------------------------------------------------------------- /src/Models/Site/Stats.php: -------------------------------------------------------------------------------- 1 | [ 18 | 'type' => 'BelongsTo', 19 | ], 20 | 'RecentMember' => [ 21 | 'type' => 'BelongsTo', 22 | 'model' => 'Member', 23 | 'from_key' => 'recent_member_id', 24 | 'weak' => true, 25 | ], 26 | ]; 27 | } 28 | -------------------------------------------------------------------------------- /resources/stubs/templates/member/management/logout.html.twig.php: -------------------------------------------------------------------------------- 1 | {% extends 'ee::/_layout' %} 2 | {% block title %}Logout{% endblock %} 3 | 4 | {% block contents %} 5 | 6 | {% if global.logged_out %} 7 | {{ exp.redirect("/login") }} 8 | {% endif %} 9 | 10 | View Template 11 | 12 | {% set form = exp.member.logout_form({return: "/login"}) %} 13 | {{ form.open() | raw }} 14 | 15 | {{ form.close() | raw }} 16 | 17 | {% endblock %} -------------------------------------------------------------------------------- /src/Support/Arguments/SearchArgument.php: -------------------------------------------------------------------------------- 1 | value = (string) $value; 12 | $this->parse($value); 13 | } 14 | 15 | protected function parse($value) 16 | { 17 | // Check for exact match 18 | if (strncasecmp($value, '=', 1) == 0) { 19 | $this->exact = true; 20 | $value = substr($value, 1); 21 | } 22 | 23 | return parent::parse($value); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/grid/field.twig.php: -------------------------------------------------------------------------------- 1 | {% for row in %} 2 | 3 | 4 | 5 | 6 | 7 | {# Grid column: #} 8 | {# Column type: #} 9 | {# Docs: #} 10 | 11 | 12 | embed($column['stub'], $column) ?> 13 | 14 | 15 | 16 | {# End Grid column: #} 17 | 18 | 19 | 20 | {% endfor %} -------------------------------------------------------------------------------- /src/Facades/Coilpack.php: -------------------------------------------------------------------------------- 1 | make('router')->coilpack($options); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/View/Tags/Member/LoginForm.php: -------------------------------------------------------------------------------- 1 | setFormAttributes(parent::run()->toArray()); 21 | 22 | return $this; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/grid/field.blade.php: -------------------------------------------------------------------------------- 1 | @foreach( as $row) 2 | 3 | {$column['col_name']}"; ?> 4 | 5 | 6 | 7 | {{-- Grid column: --}} 8 | {{-- Column type: --}} 9 | {{-- Docs: --}} 10 | 11 | 12 | embed($column['stub'], $column) ?> 13 | 14 | 15 | 16 | {{-- End Grid column: --}} 17 | 18 | 19 | 20 | @endforeach -------------------------------------------------------------------------------- /src/Models/Channel/Scopes/HideExpired.php: -------------------------------------------------------------------------------- 1 | where(function ($query) { 19 | $query->where('expiration_date', 0) 20 | ->orWhere('expiration_date', '>', now()->timestamp); 21 | }); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Models/Content/FieldData.php: -------------------------------------------------------------------------------- 1 | _table_name = $field->getDataTable(); 25 | 26 | return $this; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/View/Tags/Member/LogoutForm.php: -------------------------------------------------------------------------------- 1 | setFormAttributes(parent::run()->toArray()); 21 | 22 | return $this; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Models/Template/TemplateRoute.php: -------------------------------------------------------------------------------- 1 | 'integer', 20 | 'route_required' => \Expressionengine\Coilpack\Casts\BooleanString::class, 21 | ]; 22 | 23 | protected static $_relationships = [ 24 | 'Template' => [ 25 | 'type' => 'BelongsTo', 26 | ], 27 | ]; 28 | } 29 | -------------------------------------------------------------------------------- /src/Models/Search/SearchLog.php: -------------------------------------------------------------------------------- 1 | [ 19 | 'type' => 'BelongsTo', 20 | ], 21 | 'Member' => [ 22 | 'type' => 'BelongsTo', 23 | ], 24 | ]; 25 | 26 | public function member() 27 | { 28 | return $this->belongsTo(Member::class, 'member_id'); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/View/Tags/Member/ForgotPasswordForm.php: -------------------------------------------------------------------------------- 1 | setFormAttributes(parent::run()->toArray()); 21 | 22 | return $this; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/View/Tags/Member/ForgotUsernameForm.php: -------------------------------------------------------------------------------- 1 | setFormAttributes(parent::run()->toArray()); 21 | 22 | return $this; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Models/Comment/CommentSubscription.php: -------------------------------------------------------------------------------- 1 | belongsTo(ChannelEntry::class, 'entry_id'); 22 | } 23 | 24 | public function member() 25 | { 26 | return $this->belongsTo(Member::class, 'member_id'); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Models/Content/VariableColumnGateway.php: -------------------------------------------------------------------------------- 1 | _field_list_cache)) { 15 | return $this->_field_list_cache; 16 | } 17 | 18 | $all = ee('Database') 19 | ->newQuery() 20 | ->list_fields($this->getTableName()); 21 | 22 | $known = parent::getFieldList(); 23 | 24 | return $this->_field_list_cache = array_merge($known, $all); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Models/Session/RememberMe.php: -------------------------------------------------------------------------------- 1 | [ 19 | 'type' => 'BelongsTo', 20 | ], 21 | 'Site' => [ 22 | 'type' => 'BelongsTo', 23 | ], 24 | ]; 25 | 26 | public function member() 27 | { 28 | return $this->belongsTo(Member::class, 'member_id'); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /addon/views/overview.php: -------------------------------------------------------------------------------- 1 | extend('ee:_templates/default-nav'); ?> 2 | 3 |
    4 |
    5 |

    Version Information

    6 |
    7 | true]); 9 | $table->setColumns(['name', 'version']); 10 | $table->setData(array_map(function ($name) use ($versions) { 11 | return [$name, ltrim($versions[$name], 'v')]; 12 | }, array_keys($versions))); 13 | $this->embed('ee:_shared/table', $table->viewData(ee('CP/URL', 'coilpack/overview'))); 14 | ?> 15 | 18 |
    -------------------------------------------------------------------------------- /src/Api/Graph/Types/KeyedValue.php: -------------------------------------------------------------------------------- 1 | 'KeyedValue', 12 | 'description' => 'Key and value', 13 | ]; 14 | 15 | public function fields(): array 16 | { 17 | return [ 18 | 'key' => [ 19 | 'type' => Type::string(), 20 | 'description' => 'Key', 21 | ], 22 | 'value' => [ 23 | 'type' => Type::string(), 24 | 'description' => 'Value', 25 | ], 26 | ]; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/View/Tags/Member/MemberSearch.php: -------------------------------------------------------------------------------- 1 | setArgument('tagdata', '{!-- coilpack:fake --}'); 21 | $this->setFormAttributes(parent::run()->toArray()); 22 | 23 | return $this; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Models/Role/RoleGroup.php: -------------------------------------------------------------------------------- 1 | 'integer', 19 | ]; 20 | 21 | public function roles() 22 | { 23 | return $this->belongsToMany(Role::class, 'roles_role_groups', 'group_id', 'role_id'); 24 | } 25 | 26 | public function members() 27 | { 28 | return $this->belongsToMany(Member::class, 'members_role_groups', 'group_id', 'member_id'); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Models/Addon/Action.php: -------------------------------------------------------------------------------- 1 | functions->fetch_action_id 17 | public static function fetch_action_id($class, $method) 18 | { 19 | $action = static::select('action_id')->where('class', $class)->where('method', $method)->first(); 20 | 21 | if (! $action) { 22 | throw new \Exception("Could not find action for '$class:$method', please make sure the module is installed."); 23 | } 24 | 25 | return $action->action_id; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /addon/views/graphql.php: -------------------------------------------------------------------------------- 1 | extend('ee:_templates/default-nav'); ?> 2 | 3 | 4 | 5 |
    6 | 7 |
    8 | 9 |
    10 |
    11 |

    GraphQL

    12 |
    13 |
    14 |

    GraphQL support is currently disabled.

    15 |

    Learn how to enable and use GraphQL through the Coilpack Documentation.

    16 |
    17 |
    18 | -------------------------------------------------------------------------------- /src/Events/HookTriggered.php: -------------------------------------------------------------------------------- 1 | name = $name; 35 | $this->isActive = $isActive; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /resources/stubs/templates/channel/fieldGroups/index.twig.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | {# Field Group: #} 4 | 5 | 6 | 7 | 8 | 9 | {# Field: #} 10 | {# Fieldtype: #} 11 | {# Docs: #} 12 | 13 | 14 | 15 | embed($field['stub'], $field);?> 16 | 17 | 18 | 19 | {# End field: #} 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | {# End Field Group: #} 28 | -------------------------------------------------------------------------------- /resources/views/blade/common/_footer.html: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /resources/views/twig/common/_footer.html: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/Models/Permission/Permission.php: -------------------------------------------------------------------------------- 1 | 'integer', 20 | 'role_id' => 'integer', 21 | 'site_id' => 'integer', 22 | ]; 23 | 24 | public function role() 25 | { 26 | return $this->belongsTo(Role::class, 'role_id'); 27 | } 28 | 29 | public function site() 30 | { 31 | return $this->belongsTo(Site::class, 'site_id'); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Models/Template/SpecialtyTemplate.php: -------------------------------------------------------------------------------- 1 | \Expressionengine\Coilpack\Casts\BooleanString::class, 18 | ]; 19 | 20 | protected static $_relationships = [ 21 | 'Site' => [ 22 | 'type' => 'BelongsTo', 23 | ], 24 | 'LastAuthor' => [ 25 | 'type' => 'BelongsTo', 26 | 'model' => 'Member', 27 | 'from_key' => 'last_author_id', 28 | 'weak' => true, 29 | ], 30 | ]; 31 | } 32 | -------------------------------------------------------------------------------- /src/Fieldtypes/Modifiers/Generic.php: -------------------------------------------------------------------------------- 1 | attributes['name']; 15 | $handler = $this->fieldtype->getHandler(); 16 | 17 | return $handler->{$method}((string) $data, $parameters); 18 | } 19 | 20 | public function handle(FieldtypeOutput $content, $parameters = []) 21 | { 22 | $modified = $this->callHandler($content, $parameters); 23 | 24 | return FieldtypeOutput::for($this->fieldtype)->value($modified); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Models/Channel/ChannelEntryAutosave.php: -------------------------------------------------------------------------------- 1 | 'json', 16 | ]; 17 | 18 | public function entry() 19 | { 20 | return $this->belongsTo(ChannelEntry::class, 'original_entry_id'); 21 | } 22 | 23 | public function channel() 24 | { 25 | return $this->belongsTo(Channel::class, 'channel_id'); 26 | } 27 | 28 | public function author() 29 | { 30 | return $this->belongsTo(Member::class, 'author_id'); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Traits/ForwardsAttributes.php: -------------------------------------------------------------------------------- 1 | {$attribute}; 24 | $usingTrait = in_array(static::class, class_uses($object)); 25 | 26 | return $value; 27 | } catch (Error|BadMethodCallException $e) { 28 | return null; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /routes/web.php: -------------------------------------------------------------------------------- 1 | name('coilpack.admin'); 16 | 17 | // Recreate Route::fallback() but support ANY method not just GET 18 | $placeholder = 'fallbackPlaceholder'; 19 | Route::any( 20 | "{{$placeholder}}", 21 | [\Expressionengine\Coilpack\Controllers\FallbackController::class, 'index'] 22 | )->where($placeholder, '.*')->name('coilpack.fallback')->fallback(); 23 | // Route::fallback([Expressionengine\Coilpack\Controllers\FallbackController::class, 'index']); 24 | -------------------------------------------------------------------------------- /src/Api/Graph/Queries/VariablesQuery.php: -------------------------------------------------------------------------------- 1 | 'variables', 13 | ]; 14 | 15 | public function type(): Type 16 | { 17 | return GraphQL::type('Variables'); 18 | } 19 | 20 | public function args(): array 21 | { 22 | return [ 23 | 'site' => [ 24 | 'type' => Type::int(), 25 | ], 26 | ]; 27 | } 28 | 29 | public function resolve($root, $args) 30 | { 31 | return (new \Expressionengine\Coilpack\View\Composers\GlobalComposer)->globals()['global']; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /resources/stubs/templates/channel/fieldGroups/index.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{-- Field Group: --}} 4 | 5 | 6 | 7 | 8 | 9 | {{-- Field: --}} 10 | {{-- Fieldtype: --}} 11 | {{-- Docs: --}} 12 | 13 | 14 | {$field['field_name']}"; ?> 15 | embed($field['stub'], $field);?> 16 | 17 | 18 | 19 | {{-- End field: --}} 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | {{-- End Field Group: --}} 28 | -------------------------------------------------------------------------------- /src/Models/EntryManager/View.php: -------------------------------------------------------------------------------- 1 | 'integer', 15 | 'member_id' => 'integer', 16 | 'channel_id' => 'integer', 17 | 'name' => 'string', 18 | 'colums' => \Expressionengine\Coilpack\Casts\Serialize::class, 19 | ]; 20 | 21 | protected static $_relationships = [ 22 | 'Members' => [ 23 | 'type' => 'belongsTo', 24 | 'model' => 'Member', 25 | ], 26 | 'Channels' => [ 27 | 'type' => 'belongsTo', 28 | 'model' => 'Channel', 29 | ], 30 | ]; 31 | } 32 | -------------------------------------------------------------------------------- /resources/stubs/templates/channel/channels/index.twig.php: -------------------------------------------------------------------------------- 1 | {% set entries = exp.channel.entries({channel: "", per_page: 5}) %} 2 | {% for entry in entries %} 3 | {{ entry.title }} - {{ exp.path("/entry/", entry.url_title) }} 4 | 5 | 6 | 7 | {# Field: #} 8 | {# Fieldtype: #} 9 | {# Docs: #} 10 | 11 | 12 | 13 | 14 | embed($field['stub'], $field); ?> 15 | 16 | 17 | 18 | {# End field: #} 19 | 20 | 21 | 22 | 23 | {% endfor %} 24 | {{ entries.links }} -------------------------------------------------------------------------------- /src/View/Tag.php: -------------------------------------------------------------------------------- 1 | arguments($arguments)->run(); 27 | } 28 | 29 | /** 30 | * Cast the tag to a string by invoking the run method 31 | */ 32 | public function __toString(): string 33 | { 34 | return $this->run(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /resources/views/blade/blog/no-results.blade.php: -------------------------------------------------------------------------------- 1 | @extends('coilpack::blade/layouts/_blog-layout') 2 | 3 | {{-- prevents 4th ++ segments on no results searches --}} 4 | @if($segment_4) 5 | {{ redirect("$segment_1/$segment_2/$segment_3") }} 6 | @endif 7 | 8 | @php 9 | // page vars (prefix p_) 10 | $p_title='My Blog'; 11 | $p_description='Search Results'; 12 | $p_url='blog'; 13 | $p_url_entry='entry'; 14 | // channel vars (prefix ch_) 15 | $ch='blog'; 16 | $ch_disable='category_fields|member_data'; 17 | $search = 'y'; 18 | // layout vars 19 | $title="search results{$global->gv_sep}{$p_title}{$global->gv_sep}"; 20 | $description=$p_description; 21 | @endphp 22 | 23 | @section('blog_contents') 24 |

    Search Results, {{ $p_title }}

    25 |
    26 |

    Sorry, zero entries found matching "{{ $exp->search->keywords }}".

    27 |
    28 | @endsection -------------------------------------------------------------------------------- /src/View/Tags/Member/EditAvatar.php: -------------------------------------------------------------------------------- 1 | setArgument('tagdata', '{!-- coilpack:fake --}'); 21 | $this->setFormAttributes(parent::run()->toArray()); 22 | 23 | return $this; 24 | } 25 | 26 | public function fields() 27 | { 28 | return collect($this->getFormAttribute('fields', [])); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Api/Graph/Queries/MemberCurrentQuery.php: -------------------------------------------------------------------------------- 1 | 'me', 14 | ]; 15 | 16 | public function type(): Type 17 | { 18 | return GraphQL::type('Member'); 19 | } 20 | 21 | public function args(): array 22 | { 23 | return []; 24 | } 25 | 26 | public function resolve($root, $args) 27 | { 28 | $user = auth('coilpack')->user() ?: tap(new Member, function ($member) { 29 | $member->screen_name = 'Guest'; 30 | $member->member_id = null; 31 | }); 32 | 33 | return $user; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /resources/stubs/templates/channel/channels/index.blade.php: -------------------------------------------------------------------------------- 1 | @php 2 | $entries = $exp->channel->entries(['channel' => "", 'per_page' => 5]); 3 | @endphp 4 | 5 | @foreach($entry in $entries) 6 | {{ $entry->title }} - {{ $exp->path("/entry/", $entry->url_title) }} 7 | 8 | 9 | 10 | {{-- Field: --}} 11 | {{-- Fieldtype: --}} 12 | {{-- Docs: --}} 13 | 14 | 15 | {$field['field_name']}"; ?> 16 | 17 | embed($field['stub'], $field); ?> 18 | 19 | 20 | 21 | {{-- End field: --}} 22 | 23 | 24 | 25 | 26 | @endforeach 27 | {{ $entries->links() }} -------------------------------------------------------------------------------- /src/Dependency/NavigationSidebar.php: -------------------------------------------------------------------------------- 1 | items)) { 15 | $this->callRestrictedMethod($this, 'populateItems'); 16 | if (ee('Permission')->isSuperAdmin()) { 17 | $section = $this->addSection('Coilpack'); 18 | $section->addItem('Overview', ee('CP/URL', 'coilpack/overview'))->withIcon('list'); 19 | $section->addItem('GraphQL', ee('CP/URL', 'coilpack/graphql'))->withIcon('sitemap'); 20 | } 21 | } 22 | 23 | return parent::render(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Models/Revision/RevisionTracker.php: -------------------------------------------------------------------------------- 1 | 'integer', 18 | 'item_id' => 'integer', 19 | 'item_date' => 'integer', 20 | 'item_author_id' => 'integer', 21 | ]; 22 | 23 | protected static $_relationships = [ 24 | 'Template' => [ 25 | 'type' => 'BelongsTo', 26 | 'from_key' => 'item_id', 27 | ], 28 | 'Author' => [ 29 | 'type' => 'belongsTo', 30 | 'model' => 'Member', 31 | 'from_key' => 'item_author_id', 32 | 'weak' => true, 33 | ], 34 | ]; 35 | } 36 | -------------------------------------------------------------------------------- /src/Api/Graph/Types/Status.php: -------------------------------------------------------------------------------- 1 | 'Status', 13 | 'description' => 'Collection of statuses', 14 | 'model' => StatusModel::class, 15 | ]; 16 | 17 | public function fields(): array 18 | { 19 | return [ 20 | 'member_id' => [ 21 | 'type' => Type::nonNull(Type::int()), 22 | 'description' => 'Id of a particular entry', 23 | ], 24 | 'screen_name' => [ 25 | 'type' => Type::nonNull(Type::string()), 26 | 'description' => 'The members screen name', 27 | ], 28 | ]; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Models/Channel/ChannelEntryVersion.php: -------------------------------------------------------------------------------- 1 | 'integer', 16 | 'channel_id' => 'integer', 17 | 'author_id' => 'integer', 18 | 'version_date' => \Expressionengine\Coilpack\Casts\UnixTimestamp::class, 19 | 'version_data' => \Expressionengine\Coilpack\Casts\Serialize::class, 20 | ]; 21 | 22 | public function entry() 23 | { 24 | return $this->belongsTo(ChannelEntry::class, 'entry_id'); 25 | } 26 | 27 | public function author() 28 | { 29 | return $this->belongsTo(Member::class, 'author_id'); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Bootstrap/ConfigureStorageDisk.php: -------------------------------------------------------------------------------- 1 | set('filesystems.disks.coilpack', [ 27 | 'driver' => 'local', 28 | 'root' => realpath($basePath), 29 | ]); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Models/Addon/Extension.php: -------------------------------------------------------------------------------- 1 | 'enum[y,n]', 18 | ]; 19 | 20 | protected $casts = [ 21 | 'enabled' => \Expressionengine\Coilpack\Casts\BooleanString::class, 22 | 'settings' => \Expressionengine\Coilpack\Casts\Serialize::class, 23 | ]; 24 | 25 | /** 26 | * Marks the Extension as enabled 27 | */ 28 | public function enable() 29 | { 30 | $this->enabled = 'y'; 31 | } 32 | 33 | /** 34 | * Marks the Extension as disabled 35 | */ 36 | public function disable() 37 | { 38 | $this->enabled = 'n'; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Api/Graph/Queries/CategoryQuery.php: -------------------------------------------------------------------------------- 1 | 'category', 14 | ]; 15 | 16 | public function type(): Type 17 | { 18 | return GraphQL::type('Category'); 19 | } 20 | 21 | public function args(): array 22 | { 23 | return [ 24 | 'category_id' => [ 25 | 'name' => 'category_id', 26 | 'type' => Type::int(), 27 | 'rules' => ['required'], 28 | ], 29 | ]; 30 | } 31 | 32 | public function resolve($root, $args) 33 | { 34 | return Category::findOrFail($args['category_id']); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Api/Graph/Queries/ChannelEntryQuery.php: -------------------------------------------------------------------------------- 1 | 'channel_entry', 14 | ]; 15 | 16 | public function type(): Type 17 | { 18 | return GraphQL::type('ChannelEntry'); 19 | } 20 | 21 | public function args(): array 22 | { 23 | return [ 24 | 'entry_id' => [ 25 | 'name' => 'entry_id', 26 | 'type' => Type::int(), 27 | 'rules' => ['required'], 28 | ], 29 | ]; 30 | } 31 | 32 | public function resolve($root, $args) 33 | { 34 | return ChannelEntry::findOrFail($args['entry_id']); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Models/Message/Folder.php: -------------------------------------------------------------------------------- 1 | [ 20 | 'type' => 'belongsTo', 21 | ], 22 | ]; 23 | 24 | protected $casts = [ 25 | 'member_id' => 'integer', 26 | 'folder1_name' => 'string', 27 | 'folder2_name' => 'string', 28 | 'folder3_name' => 'string', 29 | 'folder4_name' => 'string', 30 | 'folder5_name' => 'string', 31 | 'folder6_name' => 'string', 32 | 'folder7_name' => 'string', 33 | 'folder8_name' => 'string', 34 | 'folder9_name' => 'string', 35 | 'folder10_name' => 'string', 36 | ]; 37 | } 38 | -------------------------------------------------------------------------------- /src/Casts/Serialize.php: -------------------------------------------------------------------------------- 1 | 'integer', 18 | 'consent_request_id' => 'integer', 19 | 'consent_request_version_id' => 'integer', 20 | 'member_id' => 'integer', 21 | 'log_date' => \Expressionengine\Coilpack\Casts\UnixTimestamp::class, 22 | ]; 23 | 24 | protected static $_relationships = [ 25 | 'ConsentRequest' => [ 26 | 'type' => 'belongsTo', 27 | ], 28 | 'ConsentRequestVersion' => [ 29 | 'type' => 'belongsTo', 30 | ], 31 | 'Member' => [ 32 | 'type' => 'belongsTo', 33 | ], 34 | ]; 35 | } 36 | -------------------------------------------------------------------------------- /src/Support/Arguments/NumericTerm.php: -------------------------------------------------------------------------------- 1 | ', '<', '>=', '<=', 9 | ]; 10 | 11 | protected $operator = '='; 12 | 13 | public function __construct($value) 14 | { 15 | $operator = null; 16 | $operators = static::$operators; 17 | 18 | while ($operators && ! $operator) { 19 | $find = array_pop($operators); 20 | 21 | if (strpos($value, $find) !== false) { 22 | $operator = $find; 23 | $value = str_replace($find, '', $value); 24 | } 25 | } 26 | 27 | // Convert $value to a numeric type 28 | parent::__construct($value + 0); 29 | } 30 | 31 | public function addQuery($query, $column, $boolean, $not, $exact) 32 | { 33 | return $query->where($column, $this->operator, $this->value, $boolean); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Models/Member/Online.php: -------------------------------------------------------------------------------- 1 | [ 18 | 'type' => 'belongsTo', 19 | ], 20 | 'Site' => [ 21 | 'type' => 'belongsTo', 22 | ], 23 | ]; 24 | 25 | protected $casts = [ 26 | 'online_id' => 'integer', 27 | 'site_id' => 'integer', 28 | 'member_id' => 'integer', 29 | 'in_forum' => \Expressionengine\Coilpack\Casts\BooleanString::class, 30 | 'name' => 'string', 31 | 'ip_address' => 'string', 32 | 'date' => \Expressionengine\Coilpack\Casts\UnixTimestamp::class, 33 | 'anon' => \Expressionengine\Coilpack\Casts\BooleanString::class, 34 | ]; 35 | } 36 | -------------------------------------------------------------------------------- /src/Models/File/FileDimension.php: -------------------------------------------------------------------------------- 1 | 'integer', 21 | // 'height' => 'integer' 22 | 'quality' => 'integer', 23 | ]; 24 | 25 | protected static $_relationships = [ 26 | 'UploadDestination' => [ 27 | 'type' => 'belongsTo', 28 | 'from_key' => 'upload_location_id', 29 | ], 30 | 'Watermark' => [ 31 | 'type' => 'hasOne', 32 | 'from_key' => 'watermark_id', 33 | 'to_key' => 'wm_id', 34 | ], 35 | ]; 36 | } 37 | -------------------------------------------------------------------------------- /src/Models/Message/ListedMember.php: -------------------------------------------------------------------------------- 1 | [ 21 | 'type' => 'belongsTo', 22 | 'model' => 'Member', 23 | ], 24 | 'Member' => [ 25 | 'type' => 'belongsTo', 26 | 'from_key' => 'listed_member', 27 | ], 28 | ]; 29 | 30 | protected $casts = [ 31 | 'listed_id' => 'integer', 32 | 'member_id' => 'integer', 33 | 'listed_member' => 'integer', 34 | 'listed_description' => 'string', 35 | 'listed_type' => 'string', 36 | ]; 37 | } 38 | -------------------------------------------------------------------------------- /resources/views/twig/blog/no-results.html: -------------------------------------------------------------------------------- 1 | {layout='layouts/_blog-layout'} 2 | 3 | {!-- prevents 4th ++ segments on no results searches --} 4 | {if segment_4} 5 | {redirect='{segment_1}/{segment_2}/{segment_3}'} 6 | {/if} 7 | 8 | {!-- page vars --} 9 | {preload_replace:p_title='My Blog'} 10 | {preload_replace:p_description='Search Results'} 11 | {preload_replace:p_url='blog'} 12 | {!-- channel vars (prefix ch_) --} 13 | {preload_replace:ch='blog'} 14 | {!-- layout vars, channel/page related --} 15 | {layout:set name='ch' value='{ch}'} 16 | {layout:set name='p_url' value='{p_url}'} 17 | {layout:set name='p_title' value='{p_title}'} 18 | {layout:set name='search' value='y'} 19 | {!-- layout vars --} 20 | {layout:set name='title' value='search results{gv_sep}{p_title}{gv_sep}'} 21 | {layout:set name='description' value='{p_description}'} 22 | 23 |

    Search Results, {p_title}

    24 |
    25 |

    Sorry, zero entries found matching "{exp:search:keywords}".

    26 |
    27 | -------------------------------------------------------------------------------- /src/Models/Comment/Comment.php: -------------------------------------------------------------------------------- 1 | belongsTo(ChannelEntry::class, 'entry_id'); 24 | } 25 | 26 | public function channel() 27 | { 28 | return $this->belongsTo(Channel::class, 'channel_id'); 29 | } 30 | 31 | public function author() 32 | { 33 | return $this->belongsTo(Member::class, 'member_id', 'author_id'); 34 | } 35 | 36 | public function site() 37 | { 38 | return $this->belongsTo(Site::class, 'site_id'); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Fieldtypes/Rte.php: -------------------------------------------------------------------------------- 1 | 'text_only', 15 | 'type' => 'boolean', 16 | 'description' => 'Remove all HTML tags from the content', 17 | ]), 18 | new Parameter([ 19 | 'name' => 'remove_images', 20 | 'type' => 'boolean', 21 | 'description' => 'Only remove images from the content', 22 | ]), 23 | new Parameter([ 24 | 'name' => 'images_only', 25 | 'type' => 'boolean', 26 | 'description' => 'Remove everything except images from the content', 27 | ]), 28 | ]; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Models/Site/Column/TemplatePreferences.php: -------------------------------------------------------------------------------- 1 | \Expressionengine\Coilpack\Casts\BooleanString::class, 18 | ]; 19 | 20 | protected static $_relationships = [ 21 | 'Roles' => [ 22 | 'type' => 'HasAndBelongsToMany', 23 | 'model' => 'Role', 24 | 'pivot' => [ 25 | 'table' => 'template_groups_roles', 26 | 'left' => 'template_group_id', 27 | 'right' => 'role_id', 28 | ], 29 | ], 30 | 'Templates' => [ 31 | 'type' => 'HasMany', 32 | 'model' => 'Template', 33 | ], 34 | 'Site' => [ 35 | 'type' => 'BelongsTo', 36 | ], 37 | ]; 38 | } 39 | -------------------------------------------------------------------------------- /src/Casts/Base64Serialized.php: -------------------------------------------------------------------------------- 1 | getProperty($property); 11 | $prop->setAccessible(true); 12 | 13 | return $prop->getValue($object); 14 | } 15 | 16 | protected function setRestrictedProperty($object, $property, $value) 17 | { 18 | $reflection = new \ReflectionClass($object); 19 | $prop = $reflection->getProperty($property); 20 | $prop->setAccessible(true); 21 | 22 | $prop->setValue($object, $value); 23 | } 24 | 25 | public function callRestrictedMethod($object, $method, $parameters = []) 26 | { 27 | $reflection = new \ReflectionClass($object); 28 | $method = $reflection->getMethod($method); 29 | $method->setAccessible(true); 30 | 31 | return $method->invoke($object, ...$parameters); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Models/Config/Config.php: -------------------------------------------------------------------------------- 1 | 'integer', 19 | 'site_id' => 'integer', 20 | ]; 21 | 22 | public function site() 23 | { 24 | return $this->belongsTo(Site::class, 'site_id'); 25 | } 26 | 27 | public function set__value($value) 28 | { 29 | // exception for email_newline, which uses backslashes, and is not a path variable 30 | if ($this->key != 'email_newline') { 31 | $value = str_replace('\\', '/', $value); 32 | } 33 | 34 | $this->setRawProperty('value', $value); 35 | } 36 | 37 | public function get__parsed_value() 38 | { 39 | return parse_config_variables($this->getRawProperty('value')); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

    2 | Coilpack Logo 3 |

    4 | 5 | # Coilpack 6 | 7 | Coilpack is a package that lets you harness the powerful Laravel ecosystem to bring your ExpressionEngine content forward in exciting new ways. Once installed in a standard Laravel application Coilpack loads ExpressionEngine and integrates many core services. 8 | 9 | ## Documentation 10 | 11 | Reference material for Coilpack can be found at https://expressionengine.github.io/coilpack-docs. 12 | 13 | If you have found an issue with the documentation or would like to contribute please visit the docs repository at https://github.com/expressionengine/coilpack-docs 14 | 15 | ## License 16 | 17 | Coilpack is open-sourced software licensed under the MIT license. 18 | 19 | ## Helpful Links 20 | 21 | - [ExpressionEngine](https://expressionengine.com/) 22 | - [ExpressionEngine Github](https://github.com/expressionengine/expressionengine) 23 | - [ExpressionEngine Slack](https://expressionengine.com/blog/join-us-in-slack) -------------------------------------------------------------------------------- /src/Middleware/EncryptCookies.php: -------------------------------------------------------------------------------- 1 | getPrefix()) === 0) { 20 | return true; 21 | } 22 | 23 | return parent::isDisabled($name); 24 | } 25 | 26 | /** 27 | * Get the prefix ExpressionEngine is using for its cookie names 28 | * 29 | * @return string 30 | */ 31 | protected function getPrefix() 32 | { 33 | return app('ee')->config->item('cookie_prefix') ?: 'exp_'; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Models/Channel/ChannelFieldGroup.php: -------------------------------------------------------------------------------- 1 | belongsToMany(Channel::class, 'channels_channel_field_groups', 'group_id', 'channel_id', 'group_id', 'channel_id'); 27 | } 28 | 29 | public function fields() 30 | { 31 | return $this->belongsToMany(ChannelField::class, 'channel_field_groups_fields', 'group_id', 'field_id', 'group_id', 'field_id'); 32 | } 33 | 34 | public function getShortNameAttribute($value) 35 | { 36 | return $value ?? Str::snake($this->group_name); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Casts/UnixTimestamp.php: -------------------------------------------------------------------------------- 1 | timestamp : $value; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Models/Consent/Consent.php: -------------------------------------------------------------------------------- 1 | 'integer', 18 | 'consent_request_id' => 'integer', 19 | 'consent_request_version_id' => 'integer', 20 | 'member_id' => 'integer', 21 | 'consent_given' => \Expressionengine\Coilpack\Casts\BooleanString::class, 22 | 'expiration_date' => \Expressionengine\Coilpack\Casts\UnixTimestamp::class, 23 | 'response_date' => \Expressionengine\Coilpack\Casts\UnixTimestamp::class, 24 | ]; 25 | 26 | protected static $_relationships = [ 27 | 'ConsentRequest' => [ 28 | 'type' => 'belongsTo', 29 | ], 30 | 'ConsentRequestVersion' => [ 31 | 'type' => 'belongsTo', 32 | ], 33 | 'Member' => [ 34 | 'type' => 'belongsTo', 35 | ], 36 | ]; 37 | } 38 | -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/file/field.twig.php: -------------------------------------------------------------------------------- 1 | Title: {{ .title }} 2 | URL: {{ .url }} 3 | Mime Type: {{ .mime_type }} 4 | Credit: {{ .credit }} 5 | Location: {{ .location }} 6 | File Name: {{ .file_name }} 7 | File Size: {{ .file_size }} 8 | Description: {{ .description }} 9 | Upload Directory: {{ .directory_title }} 10 | Upload Date: {{ .upload_date.format("Y m d") }} 11 | Modified Date: {{ .modified_date.format("Y m d") }} 12 | 13 | {% if .mime_type starts with 'image/' %} 14 | Width: {{ .width }} 15 | Height: {{ .height }} 16 | 17 | 18 | 19 | URL: {{ .manipulation('').url }} 20 | Width: {{ .manipulation('').width }} 21 | Height: {{ .manipulation('').height }} 22 | 23 | 24 | {% endif %} -------------------------------------------------------------------------------- /src/FieldtypeOutput.php: -------------------------------------------------------------------------------- 1 | fieldtype = $fieldtype; 16 | 17 | return $instance; 18 | } 19 | 20 | public function hasModifier($method) 21 | { 22 | return $this->fieldtype->hasModifier($method); 23 | } 24 | 25 | public function callModifier(string $name, $parameters = []) 26 | { 27 | return $this->fieldtype->callModifier($this, $name, is_array($parameters) ? $parameters : [$parameters]); 28 | } 29 | 30 | public function __call($method, $arguments) 31 | { 32 | if ($this->hasModifier($method)) { 33 | return $this->callModifier($method, ...$arguments); 34 | } 35 | 36 | if (is_null($this->object)) { 37 | return null; 38 | } 39 | 40 | return $this->object->{$method}(...$arguments); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/View/Tags/Member/EditProfile.php: -------------------------------------------------------------------------------- 1 | setArgument('tagdata', '{!-- coilpack:fake --}'); 21 | $this->setFormAttributes(parent::run()->toArray()); 22 | 23 | return $this; 24 | } 25 | 26 | public function fields() 27 | { 28 | return collect($this->getFormAttribute('fields', []))->transform(function ($field) { 29 | // Standardize our output to always call the form input element 'input' 30 | return array_merge($field, [ 31 | 'input' => $field['display_field'], 32 | ]); 33 | }); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Fieldtypes/Member.php: -------------------------------------------------------------------------------- 1 | presenter = new MemberPresenter; 19 | } 20 | 21 | public function apply(FieldContent $content, $parameters = []) 22 | { 23 | $data = $this->presenter->present($content, $parameters); 24 | 25 | return FieldtypeOutput::for($this)->value($data); 26 | } 27 | 28 | public function parametersForField(?Field $field = null): array 29 | { 30 | return $this->presenter->defineParameters(); 31 | } 32 | 33 | public function graphType() 34 | { 35 | return 'Member'; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/View/Tags/Member/RegistrationForm.php: -------------------------------------------------------------------------------- 1 | setArgument('tagdata', '{!-- coilpack:fake --}'); 21 | $this->setFormAttributes(parent::run()->toArray()); 22 | 23 | return $this; 24 | } 25 | 26 | public function fields() 27 | { 28 | return collect($this->getFormAttribute('fields', []))->transform(function ($field) { 29 | // Standardize our output to always call the form input element 'input' 30 | return array_merge($field, [ 31 | 'input' => $field['field'], 32 | ]); 33 | }); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Commands/GraphQLCommand.php: -------------------------------------------------------------------------------- 1 | option('generate-token')) { 16 | $this->generateToken(); 17 | } 18 | 19 | return self::SUCCESS; 20 | } 21 | 22 | protected function generateToken() 23 | { 24 | $token = bin2hex(random_bytes(32)); 25 | $variable = 'COILPACK_GRAPHQL_TOKEN'; 26 | $contents = file_get_contents($this->laravel->environmentFilePath()); 27 | 28 | if (strpos($contents, $variable) !== false) { 29 | $this->warn('Oops! A token is already defined.'); 30 | 31 | return; 32 | } 33 | 34 | file_put_contents($this->laravel->environmentFilePath(), 35 | $contents."\n"."$variable=$token" 36 | ); 37 | 38 | $this->info('A new token has been generated!'); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) expressionengine 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/Fieldtypes/Relationship.php: -------------------------------------------------------------------------------- 1 | presenter = new RelationshipPresenter; 19 | } 20 | 21 | public function apply(FieldContent $content, $parameters = []) 22 | { 23 | $data = $this->presenter->present($content, $parameters); 24 | 25 | return FieldtypeOutput::for($this)->value($data); 26 | } 27 | 28 | public function parametersForField(?Field $field = null): array 29 | { 30 | return $this->presenter->defineParameters(); 31 | } 32 | 33 | public function graphType() 34 | { 35 | return 'ChannelEntry'; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/file/field.blade.php: -------------------------------------------------------------------------------- 1 | Title: {{ ->title }} 2 | URL: {{ ->url }} 3 | Mime Type: {{ ->mime_type }} 4 | Credit: {{ ->credit }} 5 | Location: {{ ->location }} 6 | File Name: {{ ->file_name }} 7 | File Size: {{ ->file_size }} 8 | Description: {{ ->description }} 9 | Upload Directory: {{ ->directory_title }} 10 | Upload Date: {{ optional(->upload_date)->format("Y m d") }} 11 | Modified Date: {{ optional(->modified_date)->format("Y m d") }} 12 | 13 | @if(\Illuminate\Support\Str::startsWith(->mime_type, 'image/')) 14 | Width: {{ ->width }} 15 | Height: {{ ->height }} 16 | 17 | 18 | 19 | URL: {{ ->manipulation('')->url }} 20 | Width: {{ ->manipulation('')->width }} 21 | Height: {{ ->manipulation('')->height }} 22 | 23 | 24 | @endif -------------------------------------------------------------------------------- /src/View/Tags/Channel/Form.php: -------------------------------------------------------------------------------- 1 | setFormAttributes(parent::run()->toArray()); 21 | 22 | if (strpos($this->getFormAttribute('open'), '') !== false) { 23 | $open = $this->getFormAttribute('open'); 24 | $position = strpos($this->getFormAttribute('open'), ''); 25 | $this->setFormAttribute('open', substr($open, 0, $position)); 26 | $this->setFormAttribute('close', substr($open, $position)); 27 | } 28 | 29 | return $this; 30 | } 31 | 32 | public function fields() 33 | { 34 | return collect($this->getFormAttribute('fields', [])); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Models/Channel/ChannelLayout.php: -------------------------------------------------------------------------------- 1 | \Expressionengine\Coilpack\Casts\Serialize::class, 21 | ]; 22 | 23 | protected static $_relationships = [ 24 | 'Channel' => [ 25 | 'type' => 'belongsTo', 26 | 'key' => 'channel_id', 27 | ], 28 | 'PrimaryRoles' => [ 29 | 'type' => 'hasAndBelongsToMany', 30 | 'model' => 'Role', 31 | 'pivot' => [ 32 | 'table' => 'layout_publish_member_roles', 33 | 'key' => 'role_id', 34 | ], 35 | ], 36 | ]; 37 | 38 | public function channel() 39 | { 40 | return $this->belongsTo(Channel::class, 'channel_id'); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Models/Message/Attachment.php: -------------------------------------------------------------------------------- 1 | [ 20 | 'type' => 'belongsTo', 21 | 'from_key' => 'sender_id', 22 | ], 23 | 'Message' => [ 24 | 'type' => 'belongsTo', 25 | ], 26 | ]; 27 | 28 | protected $casts = [ 29 | 'attachment_id' => 'integer', 30 | 'sender_id' => 'integer', 31 | 'message_id' => 'integer', 32 | 'attachment_name' => 'string', 33 | 'attachment_hash' => 'string', 34 | 'attachment_extension' => 'string', 35 | 'attachment_location' => 'string', 36 | 'attachment_date' => \Expressionengine\Coilpack\Casts\UnixTimestamp::class, 37 | 'attachment_size' => 'integer', 38 | 'is_temp' => \Expressionengine\Coilpack\Casts\BooleanString::class, 39 | ]; 40 | } 41 | -------------------------------------------------------------------------------- /src/Models/Role/RoleSetting.php: -------------------------------------------------------------------------------- 1 | 'integer', 19 | 'site_id' => 'integer', 20 | 'menu_set_id' => 'integer', 21 | 'exclude_from_moderation' => \Expressionengine\Coilpack\Casts\BooleanString::class, 22 | 'search_flood_control' => 'integer', 23 | 'prv_msg_send_limit' => 'integer', 24 | 'prv_msg_storage_limit' => 'integer', 25 | 'include_in_authorlist' => \Expressionengine\Coilpack\Casts\BooleanString::class, 26 | 'include_in_memberlist' => \Expressionengine\Coilpack\Casts\BooleanString::class, 27 | 'cp_homepage_channel' => 'integer', 28 | ]; 29 | 30 | public function role() 31 | { 32 | return $this->belongsTo(Role::class); 33 | } 34 | 35 | public function site() 36 | { 37 | return $this->belongsTo(Site::class); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Api/Graph/Types/NavItem.php: -------------------------------------------------------------------------------- 1 | 'NavItem', 13 | 'description' => 'Collection of Structure navigation items', 14 | ]; 15 | 16 | public function fields(): array 17 | { 18 | return [ 19 | 'entry' => [ 20 | 'type' => GraphQL::type('ChannelEntry'), 21 | ], 22 | 'children' => [ 23 | 'type' => Type::listOf(GraphQL::type('NavItem')), 24 | ], 25 | 'depth' => [ 26 | 'type' => Type::nonNull(Type::int()), 27 | ], 28 | 'structure_url_title' => [ 29 | 'type' => Type::nonNull(Type::string()), 30 | ], 31 | 'slug' => [ 32 | 'type' => Type::nonNull(Type::string()), 33 | ], 34 | 'hidden' => [ 35 | 'type' => Type::nonNull(Type::boolean()), 36 | ], 37 | ]; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Casts/BooleanString.php: -------------------------------------------------------------------------------- 1 | isTruthy($value); 21 | } 22 | 23 | /** 24 | * Prepare the given value for storage. 25 | * 26 | * @param \Illuminate\Database\Eloquent\Model $model 27 | * @param string $key 28 | * @param array $value 29 | * @param array $attributes 30 | * @return string 31 | */ 32 | public function set($model, $key, $value, $attributes) 33 | { 34 | return ($this->isTruthy($value)) ? 'y' : 'n'; 35 | } 36 | 37 | /** 38 | * Our ee-aware truthyness check 39 | */ 40 | private function isTruthy($value) 41 | { 42 | return $value === true || $value === 'y' || $value === 1; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Models/Addon/Module.php: -------------------------------------------------------------------------------- 1 | \Expressionengine\Coilpack\Casts\BooleanString::class, 18 | 'has_publish_fields' => \Expressionengine\Coilpack\Casts\BooleanString::class, 19 | ]; 20 | 21 | public function AssignedRoles() 22 | { 23 | return $this->hasMany(Expressionengine\Coilpack\Models\Role\Role::class, 'module_member_roles'); 24 | // 'AssignedRoles' => array( 25 | // 'type' => 'hasAndBelongsToMany', 26 | // 'model' => 'Role', 27 | // 'pivot' => array( 28 | // 'table' => 'module_member_roles' 29 | // ) 30 | // ), 31 | } 32 | 33 | public function UploadDestination() 34 | { 35 | return $this->hasMany(Expressionengine\Coilpack\Models\File\UploadDestination::class); 36 | 37 | // 'UploadDestination' => array( 38 | // 'type' => 'hasMany' 39 | // ) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Support/Arguments/ListArgument.php: -------------------------------------------------------------------------------- 1 | value = (string) $value; 19 | $this->parse($value); 20 | } 21 | 22 | protected function parse($value) 23 | { 24 | $terms = array_filter(explode($this->separator, $value), function ($term) { 25 | return ! is_null($term) && trim($term) !== ''; 26 | }); 27 | 28 | $this->terms = collect(); 29 | 30 | foreach ($terms as $term) { 31 | $this->terms->push(TermFactory::make($term)); 32 | } 33 | } 34 | 35 | public function addQuery($query, $column) 36 | { 37 | if (! $query instanceof Builder && ! $query instanceof EloquentBuilder) { 38 | return $query; 39 | } 40 | 41 | $query->whereIn($column, $this->terms->pluck('value')->toArray()); 42 | 43 | return $query; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Models/Role/Role.php: -------------------------------------------------------------------------------- 1 | 'integer', 20 | 'is_locked' => \Expressionengine\Coilpack\Casts\BooleanString::class, 21 | ]; 22 | 23 | public function permissions() 24 | { 25 | return $this->hasMany(Permission::class, 'role_id'); 26 | } 27 | 28 | public function settings() 29 | { 30 | return $this->hasMany(RoleSetting::class, 'role_id'); 31 | } 32 | 33 | public function groups() 34 | { 35 | return $this->belongsToMany(RoleGroup::class, 'roles_role_groups', 'role_id', 'group_id'); 36 | } 37 | 38 | public function primaryMembers() 39 | { 40 | return $this->hasMany(Member::class, 'role_id'); 41 | } 42 | 43 | public function members() 44 | { 45 | return $this->belongsToMany(Member::class, 'members_roles', 'role_id'); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /resources/views/blade/common/_breadcrumb.blade.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/views/twig/common/_breadcrumb.twig: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/Models/File/Watermark.php: -------------------------------------------------------------------------------- 1 | \Expressionengine\Coilpack\Casts\BooleanString::class, 21 | 'wm_use_drop_shadow' => \Expressionengine\Coilpack\Casts\BooleanString::class, 22 | // 'wm_font_size' => 'integer', 23 | // 'wm_padding' => 'integer', 24 | // 'wm_opacity' => 'integer', 25 | // 'wm_hor_offset' => 'integer', 26 | // 'wm_vrt_offset' => 'integer', 27 | // 'wm_x_transp' => 'integer', 28 | // 'wm_y_transp' => 'integer', 29 | // 'wm_shadow_distance' => 'integer' 30 | ]; 31 | 32 | protected static $_relationships = [ 33 | 'FileDimension' => [ 34 | 'type' => 'belongsTo', 35 | 'from_key' => 'wm_id', 36 | 'to_key' => 'watermark_id', 37 | ], 38 | ]; 39 | } 40 | -------------------------------------------------------------------------------- /src/Models/Consent/ConsentRequest.php: -------------------------------------------------------------------------------- 1 | 'integer', 18 | 'consent_request_version_id' => 'integer', 19 | 'double_opt_in' => \Expressionengine\Coilpack\Casts\BooleanString::class, 20 | 'user_created' => \Expressionengine\Coilpack\Casts\BooleanString::class, 21 | ]; 22 | 23 | protected static $_relationships = [ 24 | 'CurrentVersion' => [ 25 | 'type' => 'belongsTo', 26 | 'model' => 'ConsentRequestVersion', 27 | 'from_key' => 'consent_request_version_id', 28 | ], 29 | 'Versions' => [ 30 | 'type' => 'hasMany', 31 | 'model' => 'ConsentRequestVersion', 32 | ], 33 | 'Consents' => [ 34 | 'type' => 'hasMany', 35 | 'model' => 'Consent', 36 | ], 37 | 'Logs' => [ 38 | 'type' => 'hasMany', 39 | 'model' => 'ConsentAuditLog', 40 | ], 41 | ]; 42 | } 43 | -------------------------------------------------------------------------------- /src/Models/Cookie/CookieSetting.php: -------------------------------------------------------------------------------- 1 | 'integer', 28 | 'cookie_provider' => 'string', 29 | 'cookie_name' => 'string', 30 | 'cookie_title' => 'string', 31 | 'cookie_description' => 'string', 32 | ]; 33 | 34 | protected static $_relationships = [ 35 | 'ConsentRequestVersion' => [ 36 | 'type' => 'hasAndBelongsToMany', 37 | 'model' => 'ConsentRequestVersion', 38 | 'pivot' => [ 39 | 'table' => 'consent_request_version_cookies', 40 | ], 41 | ], 42 | ]; 43 | } 44 | -------------------------------------------------------------------------------- /resources/views/blade/blog/search.blade.php: -------------------------------------------------------------------------------- 1 | @extends('coilpack::blade/layouts/_blog-layout') 2 | 3 | {{-- prevents 4th ++ segments on category listings --}} 4 | @if($segment_4) 5 | @if(preg_match('/^(?!P\d+).*/', $segment_4)) 6 | {{ redirect("$segment_1/$segment_2/$segment_3") }} 7 | @endif 8 | @endif 9 | 10 | {{-- prevents 5th ++ segments on paginated category listings --}} 11 | @if($segment_5) 12 | {{ redirect("$segment_1/$segment_2/$segment_3/$segment_4") }} 13 | @endif 14 | 15 | @php 16 | // page vars (prefix p_) 17 | $p_title='My Blog'; 18 | $p_description='Search Results'; 19 | $p_url='blog'; 20 | $p_url_entry='entry'; 21 | // channel vars (prefix ch_) 22 | $ch='blog'; 23 | $ch_disable='category_fields|member_data'; 24 | $search = 'y'; 25 | // layout vars 26 | $title="search results{$global->gv_sep}{$p_title}{$global->gv_sep}"; 27 | $description=$p_description; 28 | @endphp 29 | @section('blog_contents') 30 |

    Search Results, {{ $p_title }}

    31 |
    32 | @foreach($exp->search->search_results as $entry) 33 | {{-- listing as a snippet, as it's used through more than one template --}} 34 | @include('coilpack::blade/_partials/snp_blog_list') 35 | {{-- pagination --}} 36 | @include('coilpack::blade/_partials/snp_blog_list_paginate') 37 | @endforeach 38 |
    39 | @endsection -------------------------------------------------------------------------------- /resources/stubs/templates/channel/entries/feed.feed.twig.php: -------------------------------------------------------------------------------- 1 | '."\n"?> 2 | 3 | 4 | {{ global.site_name }} 5 | {{ global.site_url }} 6 | {{ global.site_description }} 7 | {% for entry in exp.channel.entries({channel: "", with: "categories"}) %} 8 | 9 | {{ entry.title }} 10 | {{ exp.path('/entry', entry.url_title) }} 11 | {{ entry.entry_date.format('r') }} 12 | {% for category in entry.categories %} 13 | {{ category.category_name }} 14 | {% endfor %} 15 | 16 | ['characters' => 120]]; ?> 17 | 18 | 19 | embed($field['stub'], $field);?> 20 | 21 | 22 | 23 | 24 | {% endfor %} 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/Models/Site/Column/ChannelPreferences.php: -------------------------------------------------------------------------------- 1 | .mime_type starts with 'image/' %} 2 | 3 | 4 | 5 | 12 | 13 | 14 | {{ <?=$field_name?>.title }} 15 | 16 | {% else %} 17 | View {{ .title }} 18 | {% endif %} 19 |
    Credit: {{ .credit }} 20 |
    Location: {{ .location }} 21 |
    File Name: {{ .file_name }} 22 |
    File Size: {{ .file_size }} 23 |
    Description: {{ .description }} 24 |
    Upload Directory: {{ .directory_title }} 25 |
    Upload Date: {{ .upload_date.format("Y m d") }} 26 |
    Modified Date: {{ .modified_date.format("Y m d") }} -------------------------------------------------------------------------------- /src/Models/Status/Status.php: -------------------------------------------------------------------------------- 1 | 'integer', 20 | 'group_id' => 'integer', 21 | 'status_order' => 'integer', 22 | ]; 23 | 24 | protected static $_relationships = [ 25 | 'Channels' => [ 26 | 'type' => 'hasAndBelongsToMany', 27 | 'model' => 'Channel', 28 | 'pivot' => [ 29 | 'table' => 'channels_statuses', 30 | ], 31 | 'weak' => true, 32 | ], 33 | 'ChannelEntries' => [ 34 | 'type' => 'hasMany', 35 | 'model' => 'ChannelEntry', 36 | 'weak' => true, 37 | ], 38 | 'Site' => [ 39 | 'type' => 'BelongsTo', 40 | ], 41 | 'Roles' => [ 42 | 'type' => 'hasAndBelongsToMany', 43 | 'model' => 'Role', 44 | 'pivot' => [ 45 | 'table' => 'statuses_roles', 46 | 'left' => 'status_id', 47 | 'right' => 'role_id', 48 | ], 49 | ], 50 | ]; 51 | } 52 | -------------------------------------------------------------------------------- /resources/stubs/templates/channel/entries/feed.feed.blade.php: -------------------------------------------------------------------------------- 1 | '."\n"?> 2 | 3 | 4 | {{ $global->site_name }} 5 | {{ $global->site_url }} 6 | {{ $global->site_description }} 7 | @foreach($exp->channel->entries(['channel' => "", 'with' => "categories"]) as $entry) 8 | 9 | {{ $entry->title }} 10 | {{ $exp->path('/entry', $entry->url_title) }} 11 | {{ $entry->entry_date->format('r') }} 12 | @foreach($entry->categories as $category) 13 | {{ $category->category_name }} 14 | @endforeach 15 | 16 | ['characters' => 120]]; ?> 17 | {$field['field_name']}"; ?> 18 | 19 | embed($field['stub'], $field);?> 20 | 21 | 22 | 23 | 24 | @endforeach 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /resources/views/twig/blog/search.html: -------------------------------------------------------------------------------- 1 | {layout='layouts/_blog-layout'} 2 | 3 | {!-- prevents 4th ++ segments on search results --} 4 | {if segment_4} 5 | {if segment_4 ~ '/^(?!P\d+).*/'} 6 | {redirect='{segment_1}/{segment_2}/{segment_3}'} 7 | {/if} 8 | {/if} 9 | 10 | {!-- prevents 5th ++ segments on paginated search results --} 11 | {if segment_5} 12 | {redirect='{segment_1}/{segment_2}/{segment_3}/{segment_4}'} 13 | {/if} 14 | 15 | {!-- page vars --} 16 | {preload_replace:p_title='My Blog'} 17 | {preload_replace:p_description='Search Results'} 18 | {preload_replace:p_url='blog'} 19 | {preload_replace:p_url_entry='entry'} 20 | {!-- channel vars (prefix ch_) --} 21 | {preload_replace:ch='blog'} 22 | {!-- layout vars, channel/page related --} 23 | {layout:set name='ch' value='{ch}'} 24 | {layout:set name='p_url' value='{p_url}'} 25 | {layout:set name='p_title' value='{p_title}'} 26 | {layout:set name='search' value='y'} 27 | {!-- layout vars --} 28 | {layout:set name='title' value='search results{gv_sep}{p_title}{gv_sep}'} 29 | {layout:set name='description' value='{p_description}'} 30 | 31 |

    Search Results, {p_title}

    32 |
    33 | {exp:search:search_results} 34 | {!-- listing as a snippet, as it's used through more than one template --} 35 | {snp_blog_list} 36 | {!-- pagination --} 37 | {snp_blog_list_paginate} 38 | {/exp:search:search_results} 39 |
    40 | -------------------------------------------------------------------------------- /src/Models/Member/MemberField.php: -------------------------------------------------------------------------------- 1 | 'json', 20 | 'm_field_exclude_from_anon' => \Expressionengine\Coilpack\Casts\BooleanString::class, 21 | 'm_legacy_field_data' => \Expressionengine\Coilpack\Casts\BooleanString::class, 22 | ]; 23 | 24 | public function getFieldType() 25 | { 26 | // We are not passing the id because Api_Channel_Fields only handles channel field ids 27 | $id = null; // $this->m_field_id 28 | 29 | // cache this 30 | return app(FieldtypeManager::class) 31 | ->make($this->m_field_type, $id, 'member') 32 | ->withSettings($this->m_field_settings); 33 | } 34 | 35 | public function getDataTableNameAttribute($value) 36 | { 37 | return "member_data_field_{$this->m_field_id}"; 38 | } 39 | 40 | public function hasLegacyFieldData() 41 | { 42 | return $this->m_legacy_field_data === 'y' || $this->m_legacy_field_data === true; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/file/field.html.blade.php: -------------------------------------------------------------------------------- 1 | @if(\Illuminate\Support\Str::startsWith(->mime_type, 'image/')) 2 | 3 | 4 | 5 | 12 | 13 | 14 | {{ <?=$field_name?>->title }} 15 | 16 | @else 17 | View {{ ->title }} 18 | @endif 19 |
    Credit: {{ ->credit }} 20 |
    Location: {{ ->location }} 21 |
    File Name: {{ ->file_name }} 22 |
    File Size: {{ ->file_size }} 23 |
    Description: {{ ->description }} 24 |
    Upload Directory: {{ ->directory_title }} 25 |
    Upload Date: {{ optional(->upload_date)->format("Y m d") }} 26 |
    Modified Date: {{ optional(->modified_date)->format("Y m d") }} -------------------------------------------------------------------------------- /src/Dependency/Container.php: -------------------------------------------------------------------------------- 1 | registry = $this->getRestrictedProperty($container, 'registry'); 15 | $this->singletonRegistry = $this->getRestrictedProperty($container, 'singletonRegistry'); 16 | 17 | return $this; 18 | } 19 | 20 | /** 21 | * Registers a dependency with the container 22 | * 23 | * @param string $name The name of the dependency in the form 24 | * Vendor:Namespace 25 | * @param Closure|obj $object The object to use 26 | * @return self Returns this InjectionContainer object 27 | */ 28 | public function overwrite($name, $object) 29 | { 30 | if (strpos($name, ':') === false) { 31 | $name = static::NATIVE_PREFIX.$name; 32 | } 33 | 34 | if ($this->has($name)) { 35 | $this->registry[$name] = (is_callable($object)) ? $object() : $object; 36 | } 37 | 38 | return $this; 39 | } 40 | 41 | public function has($name) 42 | { 43 | return array_key_exists($name, $this->registry); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Routing/CoilpackRoutes.php: -------------------------------------------------------------------------------- 1 | prependGroupNamespace('Coilpack\FallbackController')) ? null : 'Expressionengine\Coilpack\Controllers'; 17 | 18 | $this->group(['namespace' => $namespace], function () use ($options) { 19 | if ($options['admin'] ?? true) { 20 | $this->any( 21 | config('coilpack.admin_url', 'admin'), \Expressionengine\Coilpack\Controllers\AdminController::class 22 | )->name('coilpack.admin'); 23 | } 24 | 25 | if ($options['fallback'] ?? true) { 26 | // Recreate Route::fallback() but support ANY method not just GET 27 | $placeholder = 'fallbackPlaceholder'; 28 | $this->any("{{$placeholder}}", [\Expressionengine\Coilpack\Controllers\FallbackController::class, 'index']) 29 | ->where($placeholder, '.*') 30 | ->name('coilpack.fallback') 31 | ->fallback(); 32 | } 33 | }); 34 | }; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/file/field.feed.twig.php: -------------------------------------------------------------------------------- 1 | {% if .mime_type starts with 'image/' %} 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | {{ .title }} 10 | {{ .description }} 11 | {{ .credit }} 12 | 13 | 14 | {% else %} 15 | 16 | {{ .title }} 17 | {{ .description }} 18 | {{ .credit }} 19 | 20 | {% endif %} 21 | -------------------------------------------------------------------------------- /src/View/Tags/Member/Memberlist.php: -------------------------------------------------------------------------------- 1 | setArgument('paginate', 'hidden'); 21 | $this->setArgument('tagdata', '{!-- coilpack:fake --}'); 22 | $tagResult = parent::run()->toArray(); 23 | 24 | // Cast member dates 25 | $dates = [ 26 | 'last_visit', 27 | 'last_activity', 28 | 'join_date', 29 | 'last_entry_date', 30 | 'last_comment_date', 31 | 'last_forum_post_date', 32 | ]; 33 | 34 | foreach ($tagResult['member_rows'] ?? [] as $key => $row) { 35 | foreach ($dates as $date) { 36 | if (isset($row[$date]) && ! empty($row[$date])) { 37 | $tagResult['member_rows'][$key][$date] = \Carbon\Carbon::createFromTimestamp($row[$date]); 38 | } 39 | } 40 | } 41 | 42 | $this->setFormAttributes($tagResult); 43 | 44 | return $this; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /resources/stubs/templates/member/management/edit-avatar.html.blade.php: -------------------------------------------------------------------------------- 1 | @extends('ee::._layout') 2 | @section('title', 'Edit Avatar') 3 | 4 | @section('contents') 5 | 6 | @if($global->logged_out) 7 | {{ $exp->redirect("/login") }} 8 | @endif 9 | 10 | View Template 11 | 12 | @if($global->last_segment == "success") 13 |

    Avatar edited successfully!

    14 | @endif 15 | 16 |
    17 | @php 18 | $form = $exp->member->edit_avatar(['return' => "/edit-avatar/success"}) 19 | @endphp 20 | 21 | {!! $form->open() !!} 22 | Current Avatar: 23 | @if($form->avatar_url) 24 | My avatar: 25 | @else 26 | No Avatar 27 | @endif 28 | 29 |
    30 | Upload an avatar:
    31 |
    32 | 33 | 34 | 35 | @if($form->avatar_url) 36 | 37 | @endif 38 | 39 | {!! $form->close() !!} 40 |
    41 | 42 | @endsection -------------------------------------------------------------------------------- /resources/stubs/templates/member/management/edit-avatar.html.twig.php: -------------------------------------------------------------------------------- 1 | {% extends 'ee::/_layout' %} 2 | {% block title %}Edit Avatar{% endblock %} 3 | 4 | {% block contents %} 5 | 6 | {% if global.logged_out %} 7 | {{ exp.redirect("/login") }} 8 | {% endif %} 9 | 10 | View Template 11 | 12 | {% if global.last_segment == "success" %} 13 |

    Avatar edited successfully!

    14 | {% endif %} 15 | 16 |
    17 | {% set form = exp.member.edit_avatar({return: "/edit-avatar/success"}) %} 18 | 19 | {{ form.open() | raw }} 20 | Current Avatar: 21 | {% if form.avatar_url %} 22 | My avatar: 23 | {% else %} 24 | No Avatar 25 | {% endif %} 26 | 27 |
    28 | Upload an avatar:
    29 |
    30 | 31 | 32 | 33 | {% if form.avatar_url %} 34 | 35 | {% endif %} 36 | 37 | {{ form.close() | raw }} 38 |
    39 | 40 | {% endblock %} -------------------------------------------------------------------------------- /resources/stubs/fieldtypes/file/field.feed.blade.php: -------------------------------------------------------------------------------- 1 | @if(\Illuminate\Support\Str::startsWith(->mime_type, 'image/')) 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | {{ ->title }} 10 | {{ ->description }} 11 | {{ ->credit }} 12 | 13 | 14 | @else 15 | 16 | {{ ->title }} 17 | {{ ->description }} 18 | {{ ->credit }} 19 | 20 | @endif 21 | -------------------------------------------------------------------------------- /src/Middleware/MemberWithRole.php: -------------------------------------------------------------------------------- 1 | auth = $auth; 26 | } 27 | 28 | /** 29 | * Handle an incoming request. 30 | * 31 | * @param \Illuminate\Http\Request $request 32 | * @param string $role 33 | * @return mixed 34 | */ 35 | public function handle($request, Closure $next, ...$roles) 36 | { 37 | $this->authenticate($request); 38 | 39 | if ($request->user()->roles->whereIn('short_name', $roles)->isEmpty()) { 40 | throw new \Exception('Member not authorized'); 41 | } 42 | 43 | return $next($request); 44 | } 45 | 46 | protected function authenticate($request) 47 | { 48 | if ($this->auth->guard('coilpack')->check()) { 49 | return $this->auth->shouldUse('coilpack'); 50 | } 51 | 52 | throw new AuthenticationException( 53 | 'Unauthenticated.', 54 | ['coilpack'], 55 | null 56 | ); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/Controllers/FallbackController.php: -------------------------------------------------------------------------------- 1 | isAssetRequest()) { 14 | $this->middleware('coilpack'); 15 | } 16 | } 17 | 18 | public function index() 19 | { 20 | if ($this->isAssetRequest()) { 21 | (new Bootstrap\LoadExpressionEngine)->asset()->bootstrapDependencies(app()); 22 | 23 | return (new AssetController)(); 24 | } else { 25 | $core = (new Bootstrap\LoadExpressionEngine)->page()->bootstrap(app()); 26 | 27 | if (! $core) { 28 | return view('coilpack::incomplete'); 29 | } 30 | 31 | $request = Core\Request::fromGlobals(); 32 | 33 | return $core->runGlobal(); 34 | } 35 | } 36 | 37 | private function isAssetRequest() 38 | { 39 | $assetFolders = [ 40 | 'themes', 41 | 'images', 42 | ]; 43 | 44 | $path = request()->path(); 45 | $adminPrefix = trim(app('router')->getRoutes()->getByName('coilpack.admin')->getPrefix(), '/').'/'; 46 | $pieces = explode('/', strpos($path, $adminPrefix) === 0 ? substr($path, strlen($adminPrefix)) : $path); 47 | 48 | return in_array($pieces[0], $assetFolders); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Dependency/StubFactory.php: -------------------------------------------------------------------------------- 1 | getPrefix().($generatorFolder ? "/$generatorFolder" : ''), 35 | $basePath.'/fieldtypes', 36 | $basePath.'/templates/'.$provider->getPrefix().($generatorFolder ? "/$generatorFolder" : ''), 37 | $basePath.'/templates', 38 | ]); 39 | 40 | return $paths; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Middleware/MemberWithPermission.php: -------------------------------------------------------------------------------- 1 | auth = $auth; 26 | } 27 | 28 | /** 29 | * Handle an incoming request. 30 | * 31 | * @param \Illuminate\Http\Request $request 32 | * @param string $permission 33 | * @return mixed 34 | */ 35 | public function handle($request, Closure $next, ...$permissions) 36 | { 37 | $this->authenticate($request); 38 | 39 | if ($request->user()->permissions->whereIn('permission', $permissions)->isEmpty()) { 40 | throw new \Exception('Member not authorized'); 41 | } 42 | 43 | return $next($request); 44 | } 45 | 46 | protected function authenticate($request) 47 | { 48 | if ($this->auth->guard('coilpack')->check()) { 49 | return $this->auth->shouldUse('coilpack'); 50 | } 51 | 52 | throw new AuthenticationException( 53 | 'Unauthenticated.', 54 | ['coilpack'], 55 | null 56 | ); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /resources/stubs/templates/channel/entries/index.html.twig.php: -------------------------------------------------------------------------------- 1 | 2 | {!-- This template will only include title and search excerpt --} 3 | 4 | 5 | 6 | 7 | <?= $channel_title ?> 8 | 9 | 10 | 11 |
    12 |

    13 | {% set entries = exp.channel.entries({channel: "", per_page: 10}) %} 14 | {% for entry in entries %} 15 |

    {{ entry.title }}

    16 | 19 |
    20 | 21 | 22 | {# Field: #} 23 | {# Fieldtype: #} 24 | {# Docs: #} 25 | 26 | 27 | 28 | embed($field['stub'], $field); ?> 29 | 30 | 31 | 32 | {# End field: #} 33 | 34 |
    35 | 36 | {% else %} 37 |

    No entries.

    38 | {% endfor %} 39 | {{ entries.links }} 40 |
    41 | 42 | -------------------------------------------------------------------------------- /src/View/Tags/Member/CustomProfileData.php: -------------------------------------------------------------------------------- 1 | allFields('member') as $field) { 24 | $profileData[$field->m_field_name] = $member->{$field->m_field_name}; 25 | } 26 | 27 | // Cast member dates 28 | $dates = [ 29 | 'last_visit', 30 | 'last_activity', 31 | 'join_date', 32 | 'last_entry_date', 33 | 'last_comment_date', 34 | 'last_forum_post_date', 35 | ]; 36 | 37 | foreach ($dates as $date) { 38 | if (isset($profileData[$date]) && ! empty($profileData[$date])) { 39 | $profileData[$date] = \Carbon\Carbon::createFromTimestamp($profileData[$date]); 40 | } 41 | } 42 | 43 | $profileData['local_time'] = \Carbon\Carbon::now()->timezone($member->timezone ?? 'UTC'); 44 | 45 | return $profileData; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Bootstrap/SetupCacheManager.php: -------------------------------------------------------------------------------- 1 | has('cache') && ee()->cache instanceof \Expressionengine\Coilpack\CacheManager)) { 23 | return; 24 | // throw new \Exception('ExpressionEngine folder missing.'); 25 | } 26 | 27 | $overrideConfig = Arr::only(ee()->config->config, [ 28 | 'uri_protocol', 29 | 'directory_trigger', 30 | 'controller_trigger', 31 | 'function_trigger', 32 | 'enable_query_strings', 33 | ]); 34 | 35 | ee()->core->bootstrap(); 36 | 37 | // we need these variables to stay in the config after bootstrapping 38 | foreach ($overrideConfig as $key => $value) { 39 | ee()->config->set_item($key, $value); 40 | } 41 | 42 | $cache = new \Expressionengine\Coilpack\CacheManager(ee()->cache); 43 | 44 | ee()->remove('cache'); 45 | ee()->set('cache', $cache); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Models/Category/CategoryField.php: -------------------------------------------------------------------------------- 1 | 'integer', 20 | 'field_maxl' => 'integer', 21 | 'field_required' => \Expressionengine\Coilpack\Casts\BooleanString::class, 22 | 'field_show_fmt' => \Expressionengine\Coilpack\Casts\BooleanString::class, 23 | 'field_order' => 'integer', 24 | 'field_settings' => 'json', 25 | 'legacy_field_data' => \Expressionengine\Coilpack\Casts\BooleanString::class, 26 | ]; 27 | 28 | public function group() 29 | { 30 | return $this->belongsTo(CategoryGroup::class); 31 | } 32 | 33 | public function getDataTableNameAttribute($value) 34 | { 35 | return "category_field_data_field_{$this->field_id}"; 36 | } 37 | 38 | public function getFieldType() 39 | { 40 | // We are not passing the id because Api_Channel_Fields only handles channel field ids 41 | $id = null; // $this->field_id 42 | 43 | // cache this 44 | return app(FieldtypeManager::class) 45 | ->make($this->field_type, $id, 'category') 46 | ->withSettings($this->field_settings); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /resources/stubs/templates/member/management/search.html.blade.php: -------------------------------------------------------------------------------- 1 | @extends('ee::._layout') 2 | @section('title', 'Member Search') 3 | 4 | @section('contents') 5 | 6 | View Template 7 | 8 |
    9 | 10 | @php $form = $exp->member->member_search(['return' => "/index", 'inline_errors' => "yes"]); @endphp 11 | 12 | {!! $form->open() !!} 13 | @unless($form->errors()->isEmpty()) 14 |
    15 | Errors 16 | @foreach($form->errors() as $error) 17 |

    {{ $error }}

    18 | @endforeach 19 |
    20 | @endunless 21 | 22 | 28 | 29 | @if(!empty($form->options->group_id_options)) 30 | 33 | @endif 34 | 35 |
     
    36 | 37 | {!! $form->close() !!} 38 |
    39 | 40 | @endsection -------------------------------------------------------------------------------- /resources/stubs/templates/member/management/search.html.twig.php: -------------------------------------------------------------------------------- 1 | {% extends 'ee::/_layout' %} 2 | {% block title %}Member Search{% endblock %} 3 | 4 | {% block contents %} 5 | 6 | View Template 7 | 8 |
    9 | 10 | {% set form = exp.member.member_search({return: "/index", inline_errors: "yes"}) %} 11 | {{ form.open() | raw }} 12 | {% if not form.errors().isEmpty() %} 13 |
    14 | Errors 15 | {% for error in form.errors() %} 16 |

    {{ error }}

    17 | {% endfor %} 18 |
    19 | {% endif %} 20 | 21 | 27 | 28 | {% if form.options.group_id_options is not empty %} 29 | 32 | {% endif %} 33 | 34 |
     
    35 | 36 | {{ form.close() | raw }} 37 |
    38 | 39 | {% endblock %} -------------------------------------------------------------------------------- /src/Models/Message/Copy.php: -------------------------------------------------------------------------------- 1 | [ 20 | 'type' => 'belongsTo', 21 | 'model' => 'Message', 22 | ], 23 | 'Sender' => [ 24 | 'type' => 'belongsTo', 25 | 'model' => 'Member', 26 | 'from_key' => 'sender_id', 27 | ], 28 | 'Recipient' => [ 29 | 'type' => 'belongsTo', 30 | 'model' => 'Member', 31 | 'from_key' => 'recipient_id', 32 | ], 33 | ]; 34 | 35 | protected $casts = [ 36 | 'copy_id' => 'integer', 37 | 'message_id' => 'integer', 38 | 'sender_id' => 'integer', 39 | 'recipient_id' => 'integer', 40 | 'message_received' => \Expressionengine\Coilpack\Casts\BooleanString::class, 41 | 'message_read' => \Expressionengine\Coilpack\Casts\BooleanString::class, 42 | 'message_time_read' => \Expressionengine\Coilpack\Casts\UnixTimestamp::class, 43 | 'attachment_downloaded' => \Expressionengine\Coilpack\Casts\BooleanString::class, 44 | 'message_authcode' => 'string', 45 | 'message_deleted' => \Expressionengine\Coilpack\Casts\BooleanString::class, 46 | 'message_status' => 'string', 47 | ]; 48 | } 49 | -------------------------------------------------------------------------------- /src/View/TagProxy.php: -------------------------------------------------------------------------------- 1 | tags = $tags; 14 | $this->fallback = $fallback; 15 | } 16 | 17 | public function __get($key) 18 | { 19 | if ($this->hasTag($key)) { 20 | return $this->getTag($key); 21 | } 22 | 23 | return ($this->fallback) ? $this->fallback->$key : null; 24 | } 25 | 26 | public function __call($method, $arguments) 27 | { 28 | if ($this->hasTag($method)) { 29 | return $this->getTag($method)->arguments($arguments[0] ?? [])->run(); 30 | } 31 | 32 | return ($this->fallback) ? $this->fallback->$method($arguments[0] ?? []) : null; 33 | } 34 | 35 | protected function getTag($tag) 36 | { 37 | if (! $this->hasTag($tag)) { 38 | return null; 39 | } 40 | 41 | // Check that the class extends \Expressionengine\Coilpack\View\Tag 42 | return $this->hasNestedTag($tag) ? new static($this->tags[$tag]) : new $this->tags[$tag]; 43 | } 44 | 45 | protected function hasTag($tag) 46 | { 47 | return array_key_exists(strtolower($tag), $this->tags); 48 | } 49 | 50 | protected function hasNestedTag($tag) 51 | { 52 | return $this->hasTag($tag) && is_array($this->tags[$tag]); 53 | } 54 | 55 | public function __isset($key) 56 | { 57 | return true; 58 | 59 | return $this->hasTag($key); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /resources/stubs/templates/channel/entries/index.html.blade.php: -------------------------------------------------------------------------------- 1 | 2 | {{-- This template will only include title and search excerpt --}} 3 | 4 | 5 | 6 | 7 | <?= $channel_title ?> 8 | 9 | 10 | 11 |
    12 |

    13 | @php 14 | $entries = $exp->channel->entries(['channel' => "", 'per_page' => 10]); 15 | @endphp 16 | @forelse($entries as $entry) 17 |

    {{ $entry->title }}

    18 | 21 |
    22 | 23 | 24 | {{-- Field: --}} 25 | {{-- Fieldtype: --}} 26 | {{-- Docs: --}} 27 | 28 | 29 | {$field['field_name']}"; ?> 30 | embed($field['stub'], $field); ?> 31 | 32 | 33 | 34 | {{-- End field: --}} 35 | 36 |
    37 | 38 | @empty 39 |

    No entries.

    40 | @endforelse 41 | {{ $entries->links() }} 42 |
    43 | 44 | -------------------------------------------------------------------------------- /src/Api/Graph/Types/Channel.php: -------------------------------------------------------------------------------- 1 | 'Channel', 13 | 'description' => 'Collection of channels', 14 | 'model' => ChannelModel::class, 15 | ]; 16 | 17 | public function fields(): array 18 | { 19 | return [ 20 | 'channel_id' => [ 21 | 'type' => Type::nonNull(Type::int()), 22 | 'description' => 'Id of a particular entry', 23 | ], 24 | 'site_id' => [ 25 | 'type' => Type::nonNull(Type::int()), 26 | 'description' => 'Id of a particular entry', 27 | ], 28 | 'channel_name' => [ 29 | 'type' => Type::nonNull(Type::string()), 30 | 'description' => 'The members screen name', 31 | ], 32 | 'channel_title' => [ 33 | 'type' => Type::nonNull(Type::string()), 34 | 'description' => 'The members screen name', 35 | ], 36 | 'channel_url' => [ 37 | 'type' => Type::string(), 38 | 'description' => 'The members screen name', 39 | ], 40 | 'channel_description' => [ 41 | 'type' => Type::string(), 42 | 'description' => 'The members screen name', 43 | ], 44 | ]; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Controllers/Cp/Coilpack.php: -------------------------------------------------------------------------------- 1 | isSuperAdmin()) { 14 | show_error(lang('unauthorized_access'), 403); 15 | } 16 | } 17 | 18 | public function overview() 19 | { 20 | ee()->view->cp_page_title = 'Coilpack Overview'; 21 | ee()->view->cp_breadcrumbs = [ 22 | '' => 'Coilpack', 23 | ]; 24 | 25 | ee()->cp->render('coilpack:overview', [ 26 | 'header' => [ 27 | 'title' => 'Coilpack', 28 | ], 29 | 'versions' => [ 30 | 'Coilpack' => \Composer\InstalledVersions::getPrettyVersion('expressionengine/coilpack'), 31 | 'Laravel' => \Composer\InstalledVersions::getPrettyVersion('laravel/framework'), 32 | 'MySQL' => \Illuminate\Support\Facades\DB::connection('coilpack')->scalar('select version()'), 33 | 'PHP' => phpversion(), 34 | 'Twig' => \Composer\InstalledVersions::getPrettyVersion('twig/twig'), 35 | ], 36 | ]); 37 | } 38 | 39 | public function graphql() 40 | { 41 | ee()->view->cp_page_title = 'Coilpack GraphQL'; 42 | ee()->view->cp_breadcrumbs = [ 43 | ee('CP/URL')->make('coilpack/overview')->compile() => 'Coilpack', 44 | '' => 'GraphQL', 45 | ]; 46 | 47 | ee()->cp->render('coilpack:graphql'); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Models/Message/Message.php: -------------------------------------------------------------------------------- 1 | [ 18 | 'type' => 'belongsTo', 19 | 'from_key' => 'sender_id', 20 | ], 21 | 'Recipients' => [ 22 | 'type' => 'hasAndBelongsToMany', 23 | 'model' => 'Member', 24 | 'pivot' => [ 25 | 'table' => 'message_copies', 26 | 'left' => 'message_id', 27 | 'right' => 'recipient_id', 28 | ], 29 | ], 30 | ]; 31 | 32 | protected $casts = [ 33 | 'message_id' => 'integer', 34 | 'sender_id' => 'integer', 35 | 'message_date' => \Expressionengine\Coilpack\Casts\UnixTimestamp::class, 36 | 'message_subject' => 'string', 37 | 'message_body' => 'string', 38 | 'message_tracking' => \Expressionengine\Coilpack\Casts\BooleanString::class, 39 | 'message_attachments' => \Expressionengine\Coilpack\Casts\BooleanString::class, 40 | 'message_recipients' => 'string', 41 | 'message_cc' => 'string', 42 | 'message_hide_cc' => \Expressionengine\Coilpack\Casts\BooleanString::class, 43 | 'message_sent_copy' => \Expressionengine\Coilpack\Casts\BooleanString::class, 44 | 'total_recipients' => 'integer', 45 | 'message_status' => 'string', 46 | ]; 47 | } 48 | -------------------------------------------------------------------------------- /src/Bootstrap/LoadAddonFiles.php: -------------------------------------------------------------------------------- 1 | getProviders(), function ($provider) { 23 | return ! empty($provider->get('coilpack')); 24 | }); 25 | 26 | foreach ($coilpackProviders as $provider) { 27 | $bindings = $provider->get('coilpack') ?? []; 28 | $prefix = $provider->getPrefix(); 29 | 30 | foreach ($bindings['graphql']['types'] ?? [] as $name => $type) { 31 | GraphQL::addType($type, $name); 32 | } 33 | 34 | foreach ($bindings['fieldtypes'] ?? [] as $name => $class) { 35 | app(FieldtypeManager::class)->register($name, $class); 36 | } 37 | 38 | foreach ($bindings['tags'] ?? [] as $name => $class) { 39 | app(\Expressionengine\Coilpack\View\Exp::class)->registerTag("{$prefix}.{$name}", $class); 40 | } 41 | 42 | foreach ($bindings['graphql']['queries'] ?? [] as $name => $query) { 43 | GraphQL::addQuery($query, strtolower("exp_{$prefix}_{$name}")); 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Models/File/File.php: -------------------------------------------------------------------------------- 1 | [ 24 | 'type' => 'belongsTo', 25 | ], 26 | 'UploadDestination' => [ 27 | 'type' => 'belongsTo', 28 | 'to_key' => 'id', 29 | 'from_key' => 'upload_location_id', 30 | ], 31 | 'UploadAuthor' => [ 32 | 'type' => 'BelongsTo', 33 | 'model' => 'Member', 34 | 'from_key' => 'uploaded_by_member_id', 35 | ], 36 | 'ModifyAuthor' => [ 37 | 'type' => 'BelongsTo', 38 | 'model' => 'Member', 39 | 'from_key' => 'modified_by_member_id', 40 | ], 41 | 'Categories' => [ 42 | 'type' => 'hasAndBelongsToMany', 43 | 'model' => 'Category', 44 | 'pivot' => [ 45 | 'table' => 'file_categories', 46 | 'left' => 'file_id', 47 | 'right' => 'cat_id', 48 | ], 49 | ], 50 | ]; 51 | } 52 | -------------------------------------------------------------------------------- /src/Models/File/UploadDestination.php: -------------------------------------------------------------------------------- 1 | [ 24 | 'type' => 'belongsTo', 25 | ], 26 | 'Roles' => [ 27 | 'type' => 'hasAndBelongsToMany', 28 | 'model' => 'Role', 29 | 'pivot' => [ 30 | 'table' => 'upload_prefs_roles', 31 | 'left' => 'upload_id', 32 | 'right' => 'role_id', 33 | ], 34 | ], 35 | 'Module' => [ 36 | 'type' => 'belongsTo', 37 | 'model' => 'Module', 38 | 'to_key' => 'module_id', 39 | ], 40 | 'Files' => [ 41 | 'type' => 'hasMany', 42 | 'model' => 'File', 43 | 'to_key' => 'upload_location_id', 44 | ], 45 | 'FileDimensions' => [ 46 | 'type' => 'hasMany', 47 | 'model' => 'FileDimension', 48 | 'to_key' => 'upload_location_id', 49 | ], 50 | ]; 51 | } 52 | -------------------------------------------------------------------------------- /src/Models/Consent/ConsentRequestVersion.php: -------------------------------------------------------------------------------- 1 | 'integer', 18 | 'consent_request_id' => 'integer', 19 | 'create_date' => \Expressionengine\Coilpack\Casts\UnixTimestamp::class, 20 | 'author_id' => 'integer', 21 | ]; 22 | 23 | protected static $_relationships = [ 24 | 'ConsentRequest' => [ 25 | 'type' => 'belongsTo', 26 | ], 27 | 'CurrentVersion' => [ 28 | 'type' => 'belongsTo', 29 | 'model' => 'ConsentRequest', 30 | 'to_key' => 'consent_request_version_id', 31 | ], 32 | 'Consents' => [ 33 | 'type' => 'hasMany', 34 | 'model' => 'Consent', 35 | ], 36 | 'Author' => [ 37 | 'type' => 'belongsTo', 38 | 'model' => 'Member', 39 | 'from_key' => 'author_id', 40 | 'weak' => true, 41 | ], 42 | 'Logs' => [ 43 | 'type' => 'hasMany', 44 | 'model' => 'ConsentAuditLog', 45 | ], 46 | 'Cookies' => [ 47 | 'type' => 'hasAndBelongsToMany', 48 | 'model' => 'CookieSetting', 49 | 'pivot' => [ 50 | 'table' => 'consent_request_version_cookies', 51 | ], 52 | ], 53 | ]; 54 | } 55 | --------------------------------------------------------------------------------