Why ContentPart is not in ContentItem? - orchardcms

Why an fieldless ContentPart is not included in a ContentItem?
Here are code from Migrations.cs:
SchemaBuilder.CreateTable("ImageDescribedPartRecord",
table => table.ContentPartRecord());
ContentDefinitionManager.AlterPartDefinition(
"ImageDescribedPart",
cpd => cpd.WithField(
"Image",
b => b
.OfType("MediaPickerField")
.WithSetting("MediaPickerFieldSettings.Required", "false")));
ContentDefinitionManager.AlterTypeDefinition(
"PlantPicture",
cfg => cfg
.WithPart("ImageDescribedPart")
.WithPart("CommonPart", p => p.WithSetting("OwnerEditorSettings.ShowOwnerEditor", "false"))
.WithPart("BodyPart")
.WithPart("TitlePart")
.WithPart("AutoroutePart"
, builder =>
builder
.WithSetting("AutorouteSettings.AllowCustomPattern", "false")
.WithSetting("AutorouteSettings.AutomaticAdjustmentOnEdit", "true")
.WithSetting("AutorouteSettings.PatternDefinitions", "[{Name:'Container', Pattern: '{Content.Container.Path}/images/{Content.Slug}', Description: 'apgii/taxon/sub-taxon/images/title'}]")
.WithSetting("AutorouteSettings.DefaultPatternIndex", "0"))
.WithPart("ContainablePart")
.Creatable(true)
// todo: The following doesn't work. Make it work.
.WithSetting("BodyPartSettings.FlavorDefault", "text")
);
Here are code for the ContentPart:
public class ImageDescribedPart : ContentPart<ImageDescribedPartRecord>{
}
public class ImageDescribedPartRecord :ContentPartRecord {}
The following code from a driver
IContentQuery<ContentItem> query = _contentManager
.Query(VersionOptions.Published)
.Join<CommonPartRecord>()
.Where(cr => cr.Container.Id == container.Id);
var items = query.Slice(0, 10).ToList();
IEnumerable<Zulatm.WebPlants.Models.ImageDescribedPart> firstImages = items.AsPart<ImageDescribedPart>();
Logger.Debug("Items count: {0}", items.Count());
for (int i = 0; i < items.Count(); i++) {
Logger.Debug("Item {0}: {1}", i, items[i].As<TitlePart>().Title);
}
Logger.Debug("Images count: {0}",firstImages.Count());
Returns the following
2012-12-07 16:28:45,616 [35] TaxonomyNodePartDriver - Items count: 2
2012-12-07 16:28:45,617 [35] TaxonomyNodePartDriver - Item 0: Test
2012-12-07 16:28:45,619 [35] TaxonomyNodePartDriver - Item 1: test img 2
2012-12-07 16:28:45,619 [35] TaxonomyNodePartDriver - Images count: 0

You "cast" the item to a part and store it as an IEnumerable. I wonder how this doesn't cause a compile error, because this is wrong.
Most possibly the root of your problems is that if you plan to use a part directly by "casting", the part should have a corresponding driver (can be empty).

Ok. The problem was there was no Filter added in Handler. Have added ActivatorFilter:
public ImageDescribedHandler (IRepository<ImageDescribedPartRecord> repository, INavigationManager navigationManager)
{
Filters.Add(new ActivatingFilter<ImageDescribedPart>("PlantPicture"));
}
Also deleted the line for creating a table.

Related

How To Create Flutter Moor Relationship With One-To-Many Join

I have a table Category which is Related to a Task table in a one-to-many relationship and I am attempting to perform a join using Moor.
I would like to return a list for the list of tasks that match a category. How do I do it?
Stream<List<CategoryWithTask>> watchAllCategories() {
return (select(categories)
..orderBy(([
(c) => OrderingTerm(expression: c.name),
])))
.join([leftOuterJoin(tasks, tasks.categoryId.equalsExp(categories.id))])
.watch()
.map((rows) => rows.map(
(row) {
return CategoryWithTask(
category: row.readTable(categories),
task: row.readTable(tasks)); // How do I modify this line to return a list of tasks corresponding to a category?
},
).toList());
}
I managed to find a way with the support of the guys at Flutter Moor after creating an issue on Github. Below is the working code;
Stream<List<CategoryWithTasks>> watchAllCategories() {
return (select(categories)
..orderBy(([
(c) => OrderingTerm(expression: c.name),
])))
.join([leftOuterJoin(tasks, tasks.categoryId.equalsExp(categories.id))])
.watch()
.map((rows) {
final groupedData = <Category, List<Task>>{};
for (final row in rows) {
final category = row.readTable(categories);
final task = row.readTable(tasks);
final list = groupedData.putIfAbsent(category, () => []);
if (task != null) list.add(task);
}
return [
for (final entry in groupedData.entries)
CategoryWithTasks(category: entry.key, tasks: entry.value)
];
});
}

serenity-js / cucumber / chai Promise AssertionError need some assistance

Im losing it, I feel like im doing this right BUT cant figure out why this simple test fails
I got a feature file like so
Scenario: List all accounts in the tenant
Given that Keith has navigated to the tenant account list
When he views the accounts in the table that include name, name, name
Then he should also see 1,2,3 in the list
I got a definition file like so
this.When(/^(.*?) views the accounts in the table that include (.*)$/, (name: string, accountInformation: string) => {
return stage.theActorCalled(name).attemptsTo(
ViewAllAccountNames.inTheTableOf(listOf(accountInformation)),
);
});
I got a pageObject file like so
export class AccountTable {
// static displayingAll = Text.ofAll(AccountListUI.accountListView);
// static isDisplayingAllNames = Text.ofAll(Target.the('account names in the table').located(by.css('table tbody tr td:nth-child(2)')));
static AccountNames = Target.the('account names in the table').located(by.css('table tbody tr td:nth-child(2)'));
static AccountNumbers = Target.the('account numbers in the table').located(by.css('table tbody tr td:nth-child(1)'));
static isDisplayingAllNames = Text.ofAll(AccountTable.AccountNames);
static isDisplayingAllNumbers = Text.ofAll(AccountTable.AccountNumbers);
}
here is my class that does the work
constructor(private accName: string[]) {
}
static inTheTableOf(accName: string) {
return new ViewAllAccountNames(accName);
}
performAs(actor: PerformsTasks): PromiseLike<void> {
return actor.attemptsTo(
See.if(AccountTable.isDisplayingAllNames, items => expect(items).to.eventually.contain(this.accName))
);
}
}
when i debug through webstorm inside class ViewAllAccountNames i get
static inTheTableOf(accName: string) { accName: Array(3)
return new ViewAllAccountNames(accName); accName: Array(3)
}
then when i get to my See.if function I get
performAs(actor: PerformsTasks): PromiseLike<void> {
return actor.attemptsTo(
See.if(AccountTable.isDisplayingAllNames, items => expect(items).to.eventually.contain(this.accName)) AccountTable.isDisplayingAllNames: undefined
);
}
so my dilemma is this:
and I think it stems to my See.if function isnt setup in the correct way?
See.if(AccountTable.isDisplayingAllNames, items => expect(items).to.eventually.contain(this.accName))
Cucumber test run has failed.
1) Scenario: List all accounts in the tenant - e2e\features\get_account_list\get_all_accounts.feature:10
Step: When he views the accounts in the table that include name, name, name - e2e\features\get_account_list\get_all_accounts.feature:12
Step Definition: node_modules\serenity-js\src\serenity-cucumber\webdriver_synchroniser.ts:47
Message:
AssertionError: expected [ Array(5) ] to include [ 'name', 'name', 'name' ]
From: Task: <anonymous>
i am an idiot, I was using the wrong function, had to use the function
.to.eventually.contain.members
similar answer and description found here:
Answer

Multiple parents for one resource MODx Revo

I use pdoTools and I need to assign one resource to many parents, but physically it'll be in one parent category. What I already did:
Created a new TV "listParents", and in Input Options #eval return $modx->runSnippet('listParents');
Created snippet "listParents"
<?php
$criteria = $modx->newQuery('modResource');
$criteria->where(array(
'published' => 1,
'deleted' => 0,
'isfolder' => 1,
'template' => 6,
array('AND:id:!=' => 6)
));
$criteria->sortby('menuindex', 'ASC');
$collection = $modx->getCollection('modResource', $criteria);
$output = array();
foreach ($collection as $v) {
$output[] = !empty($v->get('menutitle')) ? $v->get('menutitle') : $v->get('pagetitle') . '==' . $v->get('id');
}
return implode('||', $output);
Now I can see all categories in resources: http://prntscr.com/gbq34i and can mark in which categories it should output too besides parent category http://prntscr.com/gbq9y3.
And if I want to go to one of checked categories, I should see this resource. But how can I output it via pdoTools?
I was needed to add small check:
if($isHideInMenu == '1' AND $modx->resource->get("id") != '1') {
$params['tvFilters'] = 'listParents==%' . $modx->resource->get("id") . '%';
}
The key is this line: $params['tvFilters'] = 'listParents==%' . $modx->resource->get("id") . '%';
It'll find all rows with id of current page, which stores in listParents.

How to implement a pagination for a search module in Zend Framework 2?

I have a module Search in my ZF2 application. The user fills in a search form out and gets a list of courses.
Now I'm adding the pagination to the module. The paginator is basically working: I can retrieve data over it and the pagination is displayed correctly (pagelinks 1-7 for 70 found courses with the dafault setting 10 items per page).
But it's still not usable. When I click on a pagelink, the form POST data is lost. I know -- it cannot work the way, how I implemented it (see the code below). But I have no idea, how to do it correctly, in order to eep checking the form data and nonetheless be able to use pagination.
That is my code:
Table class Search\Model\CourseTable
class CourseTable {
...
// without pagination
// public function findAllByCriteria(CourseSearchInput $input) {
// with pagination
public function findAllByCriteria(CourseSearchInput $input, $pageNumber) {
...
$select = new Select();
$where = new Where();
$having = new Having();
...
// without pagination
// $resultSet = $this->tableGateway->selectWith($select);
// return $resultSet;
// with pagination
$adapter = new \MyNamespqce\Paginator\Adapter\DbSelect($select, $this->tableGateway->getAdapter());
$paginator = new \Zend\Paginator\Paginator($adapter);
$paginator->setCurrentPageNumber($pageNumber);
return $paginator;
}
...
}
Search\Controller\SearchController
class SearchController extends AbstractActionController {
public function searchCoursesAction() {
$form = $this->getServiceLocator()->get('Search\Form\CourseSearchForm');
$request = $this->getRequest();
if ($request->isPost()) {
$courseSearchInput = new CourseSearchInput();
$form->setInputFilter($courseSearchInput->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()) {
$courseSearchInput->exchangeArray($form->getData());
// without pagination
// $courses = $this->getCourseTable()->findAllByCriteria($courseSearchInput);
// with pagination
$page = $this->params()->fromRoute('page');
$paginator = $this->getCourseTable()->findAllByCriteria($courseSearchInput, $page);
} else {
$paginator = null;
}
} else {
$paginator = null;
}
return new ViewModel(array(
'form' => $form,
// without pagination
// 'courses' => $courses,
// with pagination
'paginator' => $paginator,
'cities' => ...
));
}
...
}
How to get it working?
I also have the same problem, and I have solved it. But this is not good way. May be the idea will help you.
I solved it as follow: (Search pagination for Zend tutorial album module)
I build two action in controller named "search" and "index".
Whenever the search form submitted, it always post the value to search action. Search action build the url with search parameters, and redirect to index to disply search result.
And when the pagination links clicked, then posted values are passed through url. So whenever index action ask for search parameters, it always get the values in same format.
I defined route as follows:
'album' => array(
'type' => 'segment',
'options' => array(
'route' => '/album[/:action][/:id][/page/:page][/order_by/:order_by][/:order][/search_by/:search_by]',
'constraints' => array(
'action' => '(?!\bpage\b)(?!\border_by\b)(?!\bsearch_by\b)[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
'page' => '[0-9]+',
'order_by' => '[a-zA-Z][a-zA-Z0-9_-]*',
'order' => 'ASC|DESC',
),
'defaults' => array(
'controller' => 'Album\Controller\Album',
'action' => 'index',
),
),
),
There is a parameter named "search_by", which will keep all search parameters as a json string. This is the point, which is not good I know, but have not find any other way yet.
"Search" action build this string as -
public function searchAction()
{
$request = $this->getRequest();
$url = 'index';
if ($request->isPost()) {
$formdata = (array) $request->getPost();
$search_data = array();
foreach ($formdata as $key => $value) {
if ($key != 'submit') {
if (!empty($value)) {
$search_data[$key] = $value;
}
}
}
if (!empty($search_data)) {
$search_by = json_encode($search_data);
$url .= '/search_by/' . $search_by;
}
}
$this->redirect()->toUrl($url);
}
And next index action decode the string, do necessary action, and also send the json string to view.
public function indexAction() {
$searchform = new AlbumSearchForm();
$searchform->get('submit')->setValue('Search');
$select = new Select();
$order_by = $this->params()->fromRoute('order_by') ?
$this->params()->fromRoute('order_by') : 'id';
$order = $this->params()->fromRoute('order') ?
$this->params()->fromRoute('order') : Select::ORDER_ASCENDING;
$page = $this->params()->fromRoute('page') ? (int) $this->params()->fromRoute('page') : 1;
$select->order($order_by . ' ' . $order);
$search_by = $this->params()->fromRoute('search_by') ?
$this->params()->fromRoute('search_by') : '';
$where = new \Zend\Db\Sql\Where();
$formdata = array();
if (!empty($search_by)) {
$formdata = (array) json_decode($search_by);
if (!empty($formdata['artist'])) {
$where->addPredicate(
new \Zend\Db\Sql\Predicate\Like('artist', '%' . $formdata['artist'] . '%')
);
}
if (!empty($formdata['title'])) {
$where->addPredicate(
new \Zend\Db\Sql\Predicate\Like('title', '%' . $formdata['title'] . '%')
);
}
}
if (!empty($where)) {
$select->where($where);
}
$album = $this->getAlbumTable()->fetchAll($select);
$totalRecord = $album->count();
$itemsPerPage = 2;
$album->current();
$paginator = new Paginator(new paginatorIterator($album));
$paginator->setCurrentPageNumber($page)
->setItemCountPerPage($itemsPerPage)
->setPageRange(7);
$searchform->setData($formdata);
return new ViewModel(array(
'search_by' => $search_by,
'order_by' => $order_by,
'order' => $order,
'page' => $page,
'paginator' => $paginator,
'pageAction' => 'album',
'form' => $searchform,
'totalRecord' => $totalRecord
));
}
All the sorting and paging url contain that string.
If you know all the searching paarameters before, then you can define that at route, and pass like the same way without json string. As I have to build a common search, I have build a single string.
Source code for "Album search" is available in git hub at https://github.com/tahmina8765/zf2_search_with_pagination_example.
Live Demo: http://zf2pagination.lifencolor.com/public/album
#Sam & #automatix in the question comments are both right. My suggestion (though I'm looking for a simpler alternative) is to construct a segment route, which covers all of the options that you're likely to need and start with a standard form POST request.
Then, after the request is validated, pass the form data to the paginationControl helper as follows:
$resultsView = new ViewModel(array(
'paginator' => $paginator,
'routeParams' => array_filter($form->getData())
));
Then, in your view template, set the route parameters in the paginationControl view helper:
<?php echo $this->paginationControl($paginator, 'Sliding', 'paginator/default',
array('routeParams' => $routeParams)
) ?>
I've used array_filter here because it's a really simple way of removing any element from the form data that's null, empty or so on. That way you don't pass in extra data that you don't need.

RIA DomainService IQueryable - Select

Following a couple different tutorials, I've been trying to build a "Silverlight Business Application" against a database I've created. I've found I have two problems. The one I'm asking about here is how to filter the query.
The query that is built in the DomainService is when using the VS2010 template is:
[EnableClientAccess]
public class ChargesService : LinqToEntitiesDomainService<ChargesEntities>
{
public IQueryable<tblChargeCode> GetCharges()
{
return ObjectContext.tblChargeCodes.OrderBy(e => e.Chrgs_Code_01).Take(10);
}
}
I'm trying to create another query against the same ObjectContext.tblChargeCodes. Pulling the entire table (30 columns by ~7k rows) creates a timeout error.
I can't figure out how to do a select. I want to select Charge_Codes_01 and Bill_Description with a "starts with" type functionality (dynamic drop down search functionality). I've tried different variations of this without success. Something just isn't clicking in my brain.
public IQueryable<tblChargeCode> SearchCharges(string num)
{
var min = System.Convert.ToInt32(num.PadRight(7, '0'));
var max = System.Convert.ToInt32(num.PadRight(7, '9'));
return ObjectContext.tblChargeCodes
.Select(e => e.Chrgs_Code_01, e.Chrgs_Code_01_Desc)
.Where(e => e.Chrgs_Code_01 >= min && e.Chrgs_Code_01 <= max)
.OrderBy(e => e.Chrgs_Code_01)
.Take(10);
}
(sorry for my bad english)
The problem with you code is the "Select" - your method signature says that it must return a IQueryable of tblChargeCode, so you cannot return a projection. Here is two ways you can write your query:
In the server:
public IQueryable<tblChargeCode> SearchCharges(int min, int max, string description)
{
return ObjectContext.tblChargeCodes
.Where(e => e.Chrgs_Code_01 >= min && e.Chrgs_Code_01 <= max)
.Where(e => e.Bill_Description.StartsWith(description))
.OrderBy(e => e.Chrgs_Code_01)
.Take(10);
}
And call it on the client:
context.Load(context.SearchChargesQuery(0, 9999999, "Bill"), (op) =>
{
//op.Entities has your entities loaded
}, null);
Or you can just leave the query on the server:
public IQueryable<tblChargeCode> GetCharges()
{
return ObjectContext.tblChargeCodes.OrderBy(e => e.Chrgs_Code_01);
}
And call it from the client (it will filter on the server)
context.Load(context.GetChargesQuery().Where(e => e.Chrgs_Code_01 >= 0 && e.Chrgs_Code_01 <= 9999999)
.Where(e => e.Bill_Description.StartsWith("Bill"))
.OrderBy(e => e.Chrgs_Code_01)
.Take(10), (op) =>
{
//op.Entities has your entities loaded
}, null);
You also can use "Contains" instead of "StartsWith" in your query.

Resources