Custom search using doctrine and symfony2 - search

I want to create a searchController, that searches the db for whatever keywords the user enters into a textbox. I have looked at this article and this and many more.
This is what I have so far:
public function searchAction(Request $request) {
if ($request->getMEthod() == 'GET') {
$title = $request->get('Search_term');
//echo "<div class=\"searchText\">Search Results</div><hr/>";
$em = $this->getDoctrine()->getManager();
$Search_terms = explode(' ', $title); //splits search terms at spaces
$query = "SELECT * FROM Entity/Adverts WHERE ";
foreach ($Search_terms as $each) {
// echo $each."<br/>";
$i = 0;
$i++;
if ($i == 1)
$query .= "Adv_title LIKE '%$each%' ";
else
$query .= "OR Adv_title LIKE '%$each%' ";
}
$query = $em->createQuery($query);
$numRow = $query->count();
if ($numRow > 0) {
while ($query->fetch()) {
$repository = $em->getRepository('YCRYcrBundle:Adverts')->findBy(array(
'advTitle' => $title
));
/* echo "<h2><a href='#'> $title</a> </h2>";
echo "$desc <br /> <br />";
echo"<a href='/201308/View/YCR/index.php' class='link-button right'><span>Apply</span></a>"; */
}
}
/* else
echo "none found for \"<b>$SearchTerm </b>\"</br>Check spelling"; */
}
return $this->render('YCRYcrBundle:Search:search.html.twig', array('title' => $title->getAdvTitle()));
}
What is missing from this code to make it work, and or what is wrong?
Edit:
sorry of I was unclear. I am getting the following error:
FatalErrorException: Error: Call to undefined method Doctrine\ORM\Query::count() in C:\wamp\www\201308\src\YCR\YcrBundle\Controller\SearchController.php line 28
and do not know what is wrong as I am new to Symfony and doctrine.
This is what I have in my search.html.twig:
{% extends "YCRYcrBundle::layout.html.twig" %}
{% block content %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>YCR Job Search</title>
<link href="stylesheets/style.css" rel="stylesheet" type="text/css" />
<link href="stylesheets/colour.css" rel="stylesheet" type="text/css" />
</head>
<body onload="b = setInterval('clear()', 0);">
<div class="topDiv">
<div style="float: left;">
<img src="/201308/View/images/ycr.jpg" alt="ycr"></div>
<br/>
<!--<H2>Search for a Job</H2>-->
<div class="searchform">
<form id="formsearch" name="p" method="get" action="index.php">
<span>
<input name="Search_term" class="editbox_search" id="editbox_search" maxlength="80" value="<?php $this; ?>" type="text" />
</span>
<input type="image" name="button_search" src="images/search.gif" class="button_search" alt="" />
</form>
<br/>
<div id="search_results">
</div>
</div>
<!-- </div>-->
<script type="text/javascript" src="http://code.jquery.com/jquery- 1.7.2.min.js"></script><!--javascript jquery library-->
<script type="text/javascript" src="../View/scripts/Script.js"></script>
{% endblock %}
When the user searches, for example programmer, to display like this:
-Programmer
-a summary of the description of what a programmer entails
-a button/link that reads: read more, that takes me to a page with full description

You are pretty far off the mark. Query has no count function, that's a querybuilder function. You may write raw sql, but you are better served learning querybuilder : http://docs.doctrine-project.org/en/latest/reference/query-builder.html. Remember, doctrine is designed to give you a list of entities, that you pass to the twig to do stuff with.
Also, your twig won't do much, see the basics of usage in the very crude twig I've included. use {{entity.method}} or {{entity.field}} to get the various display properties of each entity. Use a twig foreach to loop through them all. Take a look at my example in your context, and then go read the twig documents to fill in the gaps. http://twig.sensiolabs.org/documentation
The Controller
public function searchAction(Request $request) {
if ($request->getMethod() == 'GET') {
$title = $request->get('Search_term');
$em = $this->getDoctrine()->getManager();
$qb = $em->getRepository('YCRYcrBundle:Adverts')
->createQueryBuilder('a');
$searches= explode(' ', $title);
foreach ($searches as $sk => $sv) {
$cqb[]=$qb->expr()->like("CONCAT($sv, '')", "'%$sv%'");
}
$qb->andWhere(call_user_func_array(array($qb->expr(),"orx"),$cqb));
$adverts = $qb->getResult();
}
return $this->render('YCRYcrBundle:Search:search.html.twig'
, array('adverts' => $adverts));
}
And a twig file
{# Your other stuff #}
{% for advert in adverts %}
{{advert.getId}}
{# call the various method and fields for your display#}
{% endfor %}

you need to execute the query (with execute ) or you wont get an array. and you should be using the query builder instead DQL string concatenation. Read the doctrine doc on basic doctrine usage , the entity namespace seems to be incorrect too.
i quote you :
$query = $em->createQuery($query);
$numRow = $query->count();
should be at least :
$query = $em->createQuery($query);
$numRow = count($query->execute())
edit : not sure wether you would be getting an array or an ArrayCollection , check if the count fonction works on the ArrayCollection.

Related

Showing Error Message

When I run this program and enter Dan Dan inside of it, it works. Now when I enter http://sftpgamblerlotteryclub/www it doesn't work. I would like for it to catch the sftp, /, www and return back to the form and inform the user " this is not a username, please resubmit". Thanks you.
<?php
// define variables and set to empty values
$nameErr = $emailErr = "";
$name = $email = $subject = "";
if ($_SERVER["REQUEST_METHOD"] == "POST"){
if (empty($_POST["name"])) {
$nameErr = "Name is required";
} else {
$name = test_input($_POST["name"]);
// check if name only contains letters and whitespace
if (preg_match("/^[a-zA-Z-']*$/",$name)) {
$nameErr = "Only letters and white space allowed";
}
}
}
function test_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
?>
<html>
<head>
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>Contact Form</title>
</head>
<body>
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
Name:
<input type="text" name="name">
<span class="error">* <?php echo $nameErr; ?> </span>
<br><br>
<input name="submit_btn" type="submit" id="submit-btn" value="Send Mail">
</form>
</div>
</body>
</html>
<?php
echo $name;
?>
Your test_input function is striping out the / so that is removed before you do your preg_match. As such you will never catch the /.
If I understand your question you want to make sure the user name is not in a list of prohibited names. For that I would create an array of prohibited names and then do a stripos on the json_encoded output of the array within a if condition. This makes it easy to expand the list of prohibited names.
This is based on your code snip-it.
$array = ["sftp", "http", "www"];
if (stripos(json_encode($array),$name) !== false) {
$nameErr = "This is not a valid user name"
}

Laravel 4 many to many relation paginate

Stuck for a second and for my solution did not find any answers, maybe i was searching wrong
My model
class MediaCategory extends Eloquent {
protected $table = "md_categories";
public function Media()
{
return $this->belongsToMany('Media', 'media_categories')->orderBy('id', 'DESC');
}
}
Controller
public function getCategory($slug)
{
$categories = $this->category->has('media')->orderBy('name', 'ASC')->get();
$medias = $this->category->whereSlug($slug)->get();
// $medias = $results->media();
$this->layout->title = 'Média tár';
$this->layout->content = View::make('front::page/results')
->with('categories', $categories)
->with('medias', $medias);
}
View
<div class="content-left">
#include('front::partials/search', array('categories' => $categories))
#foreach($medias as $data)
#foreach($data->media as $media)
<div class="gallery-thumbs">
<a class="view-more-image" href="{{ URL::to('media/details/'.$media->id) }}">Kép kiválasztása</a>
<a href="{{ URL::to($media->mediaOriginal()) }}" rel="prettyPhoto" title="{{ $media->title }}">
{{ HTML::image($media->mediaSmall()) }}
</a>
</div>
#endforeach
#endforeach
</div>
So when i change $medias = $this->category->whereSlug($slug)->get(); to $medias = $this->category->whereSlug($slug)->paginate(2ö); i only found sultions to the find() method
Could please someone give me a hint?
Okay, the result of not sleeping enough makes you ask stupid questions and results poor coding
Works fine, instead
$medias = $this->category->whereSlug($slug)->get();
Needed
$data = $this->category->whereSlug($slug)->first();
$medias = $data->media()->paginate(30);

How to display content from a child page within a hierarchial custom post type?

I have a hierarchical custom post type. It has 6 pages, and each page has 3 child pages.
When viewing one of the 6 pages, I need to display content (a title and excerpt) from each of its 3 child/descendent pages.
Here is my current loop:
<?php if(have_posts()):?>
<?php query_posts('&post_type=how-we-do-it&post_parent=0');?>
<?php while(have_posts()):the_post();?>
<?php $color = get_post_meta( get_the_ID(), 'pointb_how-we-do-it-color', true ); ?>
<div class="section">
<div class="title">
<h1 style="background:<?php echo $color;?> !important;">
<?php the_title();?>
</h1>
</div>
<div class="content">
<div class="how-<?php the_slug();?>">the summary here. and here is child content:
<div class="child">child content should be here.</div>
</div>
</div>
</div>
<?php endwhile;?>
<?php wp_reset_query(); ?>
<?php endif;?>
I have tried numerous different approaches to try and accomplish what I need, but none of them work within the custom post type. Here are some of the various methods I have tried:
I tried the suggested code on this page: http://wordpress.org/support/topic/display-child-pages-title-amp-content-on-parent-page
I also tried the following code:
$pageChildren = get_pages('child_of='.$post->ID');
if ( $pageChildren ) {
foreach ( $pageChildren as $pageChild ) {
echo '<h2>'. $pageChild->post_title.'</h2>
';
if ($pageChild->post_excerpt){
echo ''.$pageChild->post_excerpt.'
';
}
}
}
I've tried a number of other methods that I didn't bother saving, so I can't show them.
I'm at the point where I am getting frustrated with this and thought I'd throw it out here to get some fresh perspectives.
The issue with your first sample is that you call if(have_posts()) before you reconstruct the query.
The second sample has a dangling ' after $post->ID.
Try this:
$pageChildren = get_posts( 'post_type=how-we-do-it&post_parent='.$post->ID );
Based on some comments from MarZab above, I got thinking about the post ID.
I made the following tweak to the block of code I originally posted above, and now it works perfectly:
$pageChildren = get_pages('child_of='.$post->ID');
Is now:
$post_id = get_the_ID();
$pageChildren = get_posts( 'post_type=how-we-do-it&echo=0&post_parent='.$post_id );

Masonry Infinite Scroll with Database and Anchor Tag that links to the current document

I am new to PHP, Javascript and HTML. So maybe I'm missing something obvious but, I can't for the life of me figure out what is wrong with my code. I am trying to use Paul Irish's Infinite Scroll with a PHP file that has an anchor point that links back to itself with different GET values. The problem is that Anything I do gives me this error:
Sorry, we couldn't parse your Next (Previous Posts) URL. Verify your the css selector points to the correct A tag.
I am at my wits end and desperately need someones help because I need this done by January 20th. It's going to be a birthday gift for someone I know.
Here is my code:
index.php (Code Snippet)
<div id="content-container" class="container-fluid" style="padding:0px;overflow:hidden;">
<div class="row-fluid full">
<div class="span12 full" style="overflow:scroll;position:relative;">
<div id="media-palette">
<?php
include('content.php');
?>
</div>
</div>
</div>
</div>
script.js (Code Snippet)
$("#media-palette").infinitescroll({
navSelector:"#next",
nextSelector:"#media-palette a#next:last",
itemSelector:".media-content",
bufferPx:50,
debug: true,
}, function(newElements) {
$("#media-palette").masonry('append', newElements,true);
});
content.php
(It is worth noting that the images found in this file are for testing purposes and the final PHP file will load images from a database.)
<?php
require('dbconnect.php');
$startIndex = $_GET['start'];
$endIndex = $_GET['end'];
$nextStartIndex = $endIndex-1;
$nextEndIndex = $endIndex-10;
?>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<?php
$files = scandir("images");
if ($files) {
$length = count($files);
static $allowedExts = array("jpg", "jpeg", "gif", "png");
for ($i = 0; $i < $length; $i++) {
$extension = end(explode(".", $files[$i]));
$extension = strtolower($extension);
if (in_array($extension,$allowedExts)) {
$rand = rand(0,10);
if (!$rand) echo "<img class='media-content medium' src='images/".$files[$i]."'/>";
else echo "<img class='media-content small' src='images/".$files[$i]."'/>";
}
}
}
echo '<a id="next" href="content.php?start='.$nextStartIndex.'&end='.$nextEndIndex.'"></a>';
?>
</body>

Sitemesh layout doesn't work with g.include tag in Grails

I am rendering a view that combines a g.include invocation and a sitemesh layout.
The view would be something like this:
myview.gsp
<html>
<head>
<meta name="layout" content="checkout" />
</head>
<body>...
within the body there is an invocation to:
g.include(controller:"mycontroller", action:"myaction")
The problem is the sitemesh layout is never applied. If I remove the include invocation things work just fine.
I haven't found references to this problem in the site yet.
Has anyone found a workaround to this issue or a tip, will be much appreciated!
Thanks
-Pablo Duranti
My index file is like underlying:
<html>
<head>
<title>App Store For Publish, Download Android Apps</title>
<meta name="layout" content="main" />
<parameter name="sideBarSetting" value="main"/>
</head>
<body>
<g:if test="${flash.message}">
<div class="message">${flash.message}</div>
</g:if>
<g:announcements/>
<g:include controller="cache" action="showFeatured"/>
<g:include controller="cache" action="latestProducts"/>
<div class="push"></div>
<g:include controller="cache" action="mostPopular"/>
<div class="push"></div>
<g:include controller="cache" action="allCategories"/>
</body>
It works in Grails 1.0, 1.2.2 and now 1.3.7.
In each of actions you try to include, you can not render the view, but render the template instead. The template file can ONLY has fragments of HTML, it can NOT include the head, meta for layout, etc.
In my cache controller
def latestProducts = {
cache shared:true, validFor: 300
def htmlCacheManager = HtmlCacheManager.getInstance()
def key = 'latestProducts'
def content = htmlCacheManager.getHtmlContent(key)
if (!content) {
def products = productService.get5LatestProducts(params)
if (products){
content = g.render(template:'/common/product/productLatestListTemplate', model:['productInstanceList' : products, 'type':'latest'])
htmlCacheManager.store(key, content, Boolean.TRUE)
} else {
log.debug('No latest product found')
}
}
render content ?: ''
}
The template file:
<div class="list">
<fieldset>
<legend><g:message code="product.latest"/> <g:link action="feed" controller="product" params="['type':type]" target="_blank"><img src="${resource(dir:'images', file:'feed-icon.gif')}" height='16' width='16' alt="Feeds"/></g:link></legend>
<g:each in="${productInstanceList}" var="product">
<div class="product">
<g:render template="/common/product/productSingleListTemplate" model="['product':product]" />
</div>
</g:each>
</fieldset>
</div>

Resources