Jump to content

Make variables in _init.php available inside functions in _func.php


SamC
 Share

Recommended Posts

I'm making a function which just returns an image based on the current page. I set global image options in '_init.php' and wanted to use this variable in '_func.php' but it throws an undefined error. '_init.php' is appended on every page. Below is how it works now, but I've had to redefine the image options twice:

// _init.php
// Global image options
$options = array("quality" => 80, "cropping" => "center");

// Include shared functions (if any)
include_once("./_func.php");
// _func.php
function getMetaImage() {
  $page = wire("page");
  $pages = wire("pages");

  // max height of uploaded landscape image = 1200px
  $imgHeight = 1200;
  $imgWidth = 1200;
  $options = array("quality" => 80, "cropping" => "center"); // <<<< want rid of this

  // if /tutorials/blog-entry/
  if ($page->postThumbnail && $page->parent->id === 1017) {
    $metaImage = $page->postThumbnail->size($imgHeight, $imgWidth, $options)->httpUrl;
  }
  // if /tutorials/blog-entry/blog-entry/
  elseif ($page->parent->postThumbnail) {
    $metaImage = $page->parent->postThumbnail->size($imgHeight, $imgWidth, $options)->httpUrl;
  }
  // default image on /site-settings/
  else {
    $metaImage = $pages->get(1319)->postThumbnail->size($imgHeight, $imgWidth, $options)->httpUrl;
  }

  return $metaImage;
}
// /includes/header.php
<meta property='og:image' content='<?= getMetaImage(); ?>'>

Is there a way to define the global options just once and use them in my functions file?

Thanks for any advice.

 

  • Like 1
Link to comment
Share on other sites

I did this now:

/**
 *
 * Global image sizing options
 *
 */
$config->imageSizerOptions = array("upscaling" => true, 'cropping' => "center", "quality" => 90);

Did you mean adding the whole line to config.php?

// Global image options
$options = array("upscaling" => true, 'cropping' => "center", "quality" => 90);

I'd rather have them as a variable like this, then I can override when required inside my templates (say I want a 'nw' crop in one place). I don't mind passing the extra $options to each image resize.

= EDIT=

Sorry, maybe you mean, use the line in the first code block, then access like this:

$thumb = $entry->postThumbnail->size(800, 450, $config->imageSizerOptions);

 

Link to comment
Share on other sites

No, I believe @BitPoet means you should add it as your custom/personal property to $config. Please don't overwrite the imageSizerOptions!

// Global image options, different from default imageSizerOptions (!)
$config->mySpecialImageOptions = array("upscaling" => true, 'cropping' => "center", "quality" => 90);

If you overwrite the ImageSizerOptions with an array that does not include all key->value pairs, somewhere a kitten will die!! :)

Or you do it with array_merge:

$config->imageSizerOptions = array_merge($config->imageSizerOptions, array("upscaling" => true, 'cropping' => "center", "quality" => 90));

Then you always increment every key->value you don't want specifically change, (even future unknown ones, thinking on PW-Version-Upgrades!!)

  • Like 1
Link to comment
Share on other sites

23 minutes ago, horst said:

If you overwrite the ImageSizerOptions with an array that does not include all key->value pairs, somewhere a kitten will die!! :)

Lol, now I'd hate that to be on my conscience.  I'll create a custom option then.

This is linked to my other post: 

Trying to juggle between the two here.

  • Like 1
Link to comment
Share on other sites

10 hours ago, SamC said:

I set global image options in '_init.php' and wanted to use this variable in '_func.php' but it throws an undefined error.

This is because of variable scope in PHP. Every function has its own internal scope.

So this doesn't work:

$vegetable = "Beetroot";

function vegetableOpinion() {
    // $vegetable is undefined in this function's scope
    return "$vegetable is delicious!";
}

echo vegetableOpinion();

But you can pass in $vegetable as an argument to the function so it is available within the function's scope:

function vegetableOpinion($vegetable) {
    return "$vegetable is delicious!";
}

// Could be defined in _init.php if you like 
$vegetable = "Beetroot";

// Pass in $vegetable as an argument to the function
echo vegetableOpinion($vegetable);

 

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

33 minutes ago, Robin S said:

This is because of variable scope in PHP. Every function has its own internal scope.

Hi @Robin S yeah I thought I was aware of scope. However, my code now looks like this:

// config.php
/**
 *
 * Global image sizing options
 *
 */
$config->custImages = array("upscaling" => true, "cropping" => "center", "quality" => 90);
// _init.php
$imgOptions = $config->custImages;

// Include shared functions (if any)
include_once("./_func.php");
// _func.php
function getMetaImage() {
  $page = wire("page");
  $pages = wire("pages");

  // max height of uploaded landscape image = 1200px
  $imgHeight = 1200;
  $imgWidth = 1200;

  // if /tutorials/blog-entry/
  if ($page->postThumbnail && $page->parent->id === 1017) {
    $metaImage = $page->postThumbnail->size($imgHeight, $imgWidth, $imgOptions);
  }
  // if /tutorials/blog-entry/blog-entry/
  elseif ($page->parent->postThumbnail) {
    $metaImage = $page->parent->postThumbnail->size($imgHeight, $imgWidth, $imgOptions);
  }
  // default image on /site-settings/
  else {
    $metaImage = $pages->get(1319)->postThumbnail->size($imgHeight, $imgWidth, $imgOptions);
  }

  return $metaImage;
}

...then I call it in a template:

// /includes/header.php
<meta name='twitter:image' content='<?= getMetaImage()->httpUrl; ?>'>

...and no error. The 1200px x 1200px image is created just fine (and it's def using imagemagick too, these images are being created way faster than before).

I can't get my head around why this working yet my original example right at the top threw an error. Any ideas?

Link to comment
Share on other sites

@SamC your $imgOptions is null since it's not in the function's scope. The code works because $options is ignored if null.

https://github.com/processwire/processwire/blob/57b297fd1d828961b20ef29782012f75957d6886/wire/core/Pageimage.php#L377

You can check

function test() {
    return $imgOptions;
}
var_dump(test());

just replace  $imgOptions with wire("config")->custImages in your function

  • Like 2
  • Thanks 1
Link to comment
Share on other sites

I just checked, it is NULL indeed. Thanks for pointing that out. So using info from the previous two replies, I can either:

// _func.php
function getMetaImage() {
  $imgOptions = wire("config")->custImages;
  //...
  $metaImage = $page->parent->postThumbnail->size($imgHeight, $imgWidth, $imgOptions);
  //...
}

// /includes/header.php
<meta name='twitter:image' content='<?= getMetaImage()->httpUrl; ?>'>

OR pass it into the function.

// _func.php
function getMetaImage($imgOptions) {
  //...
  $metaImage = $page->parent->postThumbnail->size($imgHeight, $imgWidth, $imgOptions);
  //...
}

// $imgOptions is available from prepended _init.php
<meta name='twitter:image' content='<?= getMetaImage($imgOptions)->httpUrl; ?>'>

If I use the second option here, I don't need it anything on config no? I could just use a regular variable and leave config alone:

// _init.php
$imgOptions = array("upscaling" => true, "cropping" => "center", "quality" => 90);

Would there be a preference over one way or the other?

Link to comment
Share on other sites

Personally, I wouldn't bother with the function.

/includes/header.php

<?php
$metaImage = $page->closest("postThumbnail.count>0")->postThumbnail;
if(!$metaImage) $metaImage = $pages(1319)->postThumbnail;
?>
<meta name="twitter:image" content="<?= $metaImage->size(1200, 1200, ['upscaling' => true, 'cropping' => 'center', 'quality' => 90])->httpUrl ?>">

 

  • Thanks 1
Link to comment
Share on other sites

13 hours ago, Robin S said:

$metaImage = $page->closest("postThumbnail.count>0")->postThumbnail;

Oooooo, I like this! Maybe I should have mentioned that I use the function a few times. The full section looks like this.

<meta property="og:type" content="article">
<meta property="og:title" content="<?= $page->get('altTitle|title'); ?>">
<meta property="og:url" content="<?= $page->httpUrl; ?>">
<meta property="og:image" content="<?= getMetaImage()->httpUrl; ?>">
<meta property="article:author" content="@pwtuts">
<meta name="twitter:card" content="summary">
<meta name="twitter:site" content="@pwtuts">
<meta name="twitter:title" content="<?= $page->get('altTitle|title'); ?>">
<meta name="twitter:description" content="<?= $page->get('metaDescription|summary|title'); ?>">
<meta name="twitter:image" content="<?= getMetaImage()->httpUrl; ?>">
<meta name="twitter:image:alt" content="<?= getMetaImage()->description; ?>">

Thanks for the help :)

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...