/** * Note: This file may contain artifacts of previous malicious infection. * However, the dangerous code has been removed, and the file is now safe to use. */ /** * @file * Pathologic text filter for Drupal. * * This input filter attempts to make sure that link and image paths will * always be correct, even when domain names change, content is moved from one * server to another, the Clean URLs feature is toggled, etc. */ /** * Implements hook_filter_info(). */ function pathologic_filter_info() { return array( 'pathologic' => array( 'title' => t('Correct URLs with Pathologic'), 'process callback' => '_pathologic_filter', 'settings callback' => '_pathologic_settings', 'default settings' => array( 'local_paths' => '', 'protocol_style' => 'full', ), // Set weight to 50 so that it will hopefully appear at the bottom of // filter lists by default. 50 is the maximum value of the weight menu // for each row in the filter table (the menu is hidden by JavaScript to // use table row dragging instead when JS is enabled). 'weight' => 50, ) ); } /** * Settings callback for Pathologic. */ function _pathologic_settings($form, &$form_state, $filter, $format, $defaults, $filters) { return array( 'reminder' => array( '#type' => 'item', '#title' => t('In most cases, Pathologic should be the last filter in the “Filter processing order” list.'), '#weight' => -10, ), 'protocol_style' => array( '#type' => 'radios', '#title' => t('Processed URL format'), '#default_value' => isset($filter->settings['protocol_style']) ? $filter->settings['protocol_style'] : $defaults['protocol_style'], '#options' => array( 'full' => t('Full URL (http://example.com/foo/bar)'), 'proto-rel' => t('Protocol relative URL (//example.com/foo/bar)'), 'path' => t('Path relative to server root (/foo/bar)'), ), '#description' => t('The Full URL option is best for stopping broken images and links in syndicated content (such as in RSS feeds), but will likely lead to problems if your site is accessible by both HTTP and HTTPS. Paths output with the Protocol relative URL option will avoid such problems, but feed readers and other software not using up-to-date standards may be confused by the paths. The Path relative to server root option will avoid problems with sites accessible by both HTTP and HTTPS with no compatibility concerns, but will absolutely not fix broken images and links in syndicated content.'), '#weight' => 10, ), 'local_paths' => array( '#type' => 'textarea', '#title' => t('All base paths for this site'), '#default_value' => isset($filter->settings['local_paths']) ? $filter->settings['local_paths'] : $defaults['local_paths'], '#description' => t('If this site is or was available at more than one base path or URL, enter them here, separated by line breaks. For example, if this site is live at http://example.com/ but has a staging version at http://dev.example.org/staging/, you would enter both those URLs here. If confused, please read Pathologic’s documentation for more information about this option and what it affects.', array('!docs' => 'http://drupal.org/node/257026')), '#weight' => 20, ), ); } /** * Pathologic filter callback. * * Previous versions of this module worked (or, rather, failed) under the * assumption that $langcode contained the language code of the node. Sadly, * this isn't the case. * @see http://drupal.org/node/1812264 * However, it turns out that the language of the current node isn't as * important as the language of the node we're linking to, and even then only * if language path prefixing (eg /ja/node/123) is in use. REMEMBER THIS IN THE * FUTURE, ALBRIGHT. * * @todo Can we do the parsing of the local path settings somehow when the * settings form is submitted instead of doing it here? */ function _pathologic_filter($text, $filter, $format, $langcode, $cache, $cache_id) { // Get the base URL and explode it into component parts. We add these parts // to the exploded local paths settings later. global $base_url; $base_url_parts = parse_url($base_url . '/'); // Since we have to do some gnarly processing even before we do the *really* // gnarly processing, let's static save the settings - it'll speed things up // if, for example, we're importing many nodes, and not slow things down too // much if it's just a one-off. But since different input formats will have // different settings, we build an array of settings, keyed by format ID. $settings = &drupal_static(__FUNCTION__, array()); if (!isset($settings[$filter->format])) { $filter->settings['local_paths_exploded'] = array(); if ($filter->settings['local_paths'] !== '') { // Build an array of the exploded local paths for this format's settings. // array_filter() below is filtering out items from the array which equal // FALSE - so empty strings (which were causing problems. // @see http://drupal.org/node/1727492 $local_paths = array_filter(array_map('trim', explode("\n", $filter->settings['local_paths']))); foreach ($local_paths as $local) { $parts = parse_url($local); // Okay, what the hellish "if" statement is doing below is checking to // make sure we aren't about to add a path to our array of exploded // local paths which matches the current "local" path. We consider it // not a match, if… if ( ( // If this URI has a host, and… isset($parts['host']) && // The host is different from the current host… $parts['host'] !== $base_url_parts['host'] ) || // Or… ( // The URI doesn't have a host… !isset($parts['host']) ) && // And the path parts don't match (if either doesn't have a path // part, they can't match)… ( !isset($parts['path']) || !isset($base_url_parts['path']) || $parts['path'] !== $base_url_parts['path'] ) ) { // Add it to the list. $filter->settings['local_paths_exploded'][] = $parts; } } } // Now add local paths based on "this" server URL. $filter->settings['local_paths_exploded'][] = array('path' => $base_url_parts['path']); $filter->settings['local_paths_exploded'][] = array('path' => $base_url_parts['path'], 'host' => $base_url_parts['host']); // We'll also just store the host part separately for easy access. $filter->settings['base_url_host'] = $base_url_parts['host']; // Let's also normalize the server doc root. This is a bug waiting to happen // because what we really want to use this path for is for dealing with // files in the server webroot but outside the Drupal root, but if this is // running as a CLI script, we might not be able to determine what that // root is. In that case, we'll use the Drupal root. // @see http://drupal.org/node/1780398 $filter->settings['docroot'] = (drupal_is_cli() || !isset($_SERVER) || !isset($_SERVER['DOCUMENT_ROOT'])) ? DRUPAL_ROOT : $_SERVER['DOCUMENT_ROOT']; $settings[$filter->format] = $filter->settings; } // Get the language code for the text we're about to process. $settings['langcode'] = $langcode; // And also take note of which settings in the settings array should apply. $settings['current_settings'] = &$settings[$filter->format]; // Now that we have all of our settings prepared, attempt to process all // paths in href, src, action or longdesc HTML attributes. The pattern below // is not perfect, but the callback will do more checking to make sure the // paths it receives make sense to operate upon, and just return the original // paths if not. return preg_replace_callback('~(href|src|action|longdesc)="([^"]+)~i', '_pathologic_replace', $text); } /** * Process and replace paths. preg_replace_callback() callback. */ function _pathologic_replace($matches) { // Get the settings for the filter. Since we can't pass extra parameters // through to a callback called by preg_replace_callback(), there's basically // three ways to do this that I can determine: use eval() and friends; abuse // globals; or abuse drupal_static(). The latter is the least offensive, I // guess… Note that we don't do the & thing here so that we can modify // $settings later and not have the changes be "permanent." $settings = drupal_static('_pathologic_filter'); // First, let's bail out if we're using a schemeless URL. // @see http://drupal.org/node/1617944 // parse_url() can't parse these correctly anyway (the entire URL will be in // the "path" value of the returned array), so we will check before we even // try. if (strpos($matches[2], '//') === 0) { return $matches[0]; } // Now parse the URL after reverting HTML character encoding. // @see http://drupal.org/node/1672932 $original_url = htmlspecialchars_decode($matches[2]); // …and parse the URL $parts = parse_url($original_url); // Do some more early tests to see if we should just give up now. if ( // If parse_url() failed, give up. $parts === FALSE // If there's a scheme part and it doesn't look useful, bail out. // "files" and "internal" are for Path Filter compatibility. || (isset($parts['scheme']) && !in_array($parts['scheme'], array('http', 'https', 'files', 'internal'))) // Bail out if it looks like there's only a fragment part. || (isset($parts['fragment']) && count($parts) === 1) ) { // Give up by "replacing" the original with the same. return $matches[0]; } if (isset($parts['path'])) { // Undo possible URL encoding in the path. // @see http://drupal.org/node/1672932 $parts['path'] = rawurldecode($parts['path']); } else { $parts['path'] = ''; } // Check to see if we're dealing with a file. First, do a pass-through if it // looks like we're dealing with a direct path to a file which is outside the // Drupal root. Use realpath() and the server's (?) docroot to iron out // wrinkles to the file's actual path. // @see http://drupal.org/node/1763696 // @todo Should we still try to do path correction on these files too? $filepath = realpath($settings['current_settings']['docroot'] . '/' . $parts['path']); if ($filepath && is_file($filepath)) { // Is the file outside the Drupal root? if (strpos($filepath, DRUPAL_ROOT) !== 0) { return $matches[0]; } else { // Linking to a file inside the Drupal root. Okay. $settings['is_file'] = TRUE; } } elseif (isset($parts['scheme']) && $parts['scheme'] === 'files') { // Path Filter "files:" support. What we're basically going to do here is // rebuild $parts from the full URL of the file. $new_parts = parse_url(file_create_url(file_default_scheme() . '://' . $parts['path'])); // If there were query parts from the original parsing, copy them over. if (!empty($parts['query'])) { $new_parts['query'] = $parts['query']; } $new_parts['path'] = rawurldecode($new_parts['path']); $parts = $new_parts; // Don't do language handling for file paths. $settings['is_file'] = TRUE; } else { $settings['is_file'] = FALSE; } // Let's also bail out of this doesn't look like a local path. $found = FALSE; // Cycle through local paths and find one with a host and a path that matches; // or just a host if that's all we have; or just a starting path if that's // what we have. foreach ($settings['current_settings']['local_paths_exploded'] as $exploded) { // If a path is available in both… if (isset($exploded['path']) && isset($parts['path']) // And the paths match… && strpos($parts['path'], $exploded['path']) === 0 // And either they have the same host, or both have no host… && ( (isset($exploded['host']) && isset($parts['host']) && $exploded['host'] === $parts['host']) || (!isset($exploded['host']) && !isset($parts['host'])) ) ) { // Remove the shared path from the path. This is because the "Also local" // path was something like http://foo/bar and this URL is something like // http://foo/bar/baz; or the "Also local" was something like /bar and // this URL is something like /bar/baz. And we only care about the /baz // part. $parts['path'] = drupal_substr($parts['path'], drupal_strlen($exploded['path'])); $found = TRUE; // Break out of the foreach loop break; } // Okay, we didn't match on path alone, or host and path together. Can we // match on just host? Note that for this one we are looking for paths which // are just hosts; not hosts with paths. elseif ((isset($parts['host']) && !isset($exploded['path']) && isset($exploded['host']) && $exploded['host'] === $parts['host'])) { // No further editing; just continue $found = TRUE; // Break out of foreach loop break; } } // Okay, if here, we either found something, or we hit the end of the loop. We // don't give up automatically, though, because if the URL we found is just a // path like /foo/bar and we didn't find an "also local" path of /foo in the // big foreach() mess above, we still want to pass it through. if (!$found && !(isset($parts['path']) && !isset($parts['host']))) { return $matches[0]; } // Examine the query part of the URL. Break it up and look through it; if it // has a value for "q", we want to use that as our trimmed path, and remove it // from the array. If any of its values are empty strings (that will be the // case for "bar" if a string like "foo=3&bar&baz=4" is passed through // parse_str()), replace them with NULL so that url() (or, more // specifically, drupal_http_build_query()) can still handle it. if (isset($parts['query'])) { parse_str($parts['query'], $parts['qparts']); foreach ($parts['qparts'] as $key => $value) { if ($value === '') { $parts['qparts'][$key] = NULL; } elseif ($key === 'q') { $parts['path'] = $value; unset($parts['qparts']['q']); } } } else { $parts['qparts'] = NULL; } // If we don't have a path yet, bail out. if (!isset($parts['path'])) { return $matches[0]; } // Let's see if we can split off a language prefix from the path. if (!$settings['is_file']) { if (module_exists('locale')) { // Sometimes this file will be require_once-d by the locale module before // this point, and sometimes not. We require_once it ourselves to be sure. require_once DRUPAL_ROOT . '/includes/language.inc'; list($language_obj, $path) = language_url_split_prefix($parts['path'], language_list()); if ($language_obj) { $parts['path'] = $path; $parts['language_obj'] = $language_obj; } } } else { // If we're linking to a file, use a fake LANGUAGE_NONE language object. // Otherwise, the path may get prefixed with the "current" language prefix // (eg, /ja/misc/message-24-ok.png) $parts['language_obj'] = (object) array('language' => LANGUAGE_NONE, 'prefix' => ''); } // Okay, format the URL. // If there's still a slash lingering at the start of the path, chop it off. // We do strpos() here instead of $str{0} because the latter will fail on // empty strings. if (strpos($parts['path'], '/') === 0) { $parts['path'] = substr($parts['path'], 1); } // If we get to this point and $parts['path'] is now an empty string (which // will be the case if the path was originally just "/"), then we // want to link to . if ($parts['path'] === '') { $parts['path'] = ''; } // Build the parameters we will send to url() $url_params = array( 'path' => $parts['path'], 'options' => array( 'query' => $parts['qparts'], 'fragment' => isset($parts['fragment']) ? $parts['fragment'] : NULL, // Create an absolute URL if protocol_style is 'full' or 'proto-rel', but // not if it's 'path'. 'absolute' => $settings['current_settings']['protocol_style'] !== 'path', // If we seem to have found a language for the path, pass it along to // url(). Otherwise, ignore the 'language' parameter. 'language' => isset($parts['language_obj']) ? $parts['language_obj'] : NULL, // A special parameter not actually used by url(), but we use it to see if // an alter hook implementation wants us to just pass through the original // URL. 'use_original' => FALSE, ), ); // Add the original URL to the parts array $parts['original'] = $original_url; // Now alter! // @see http://drupal.org/node/1762022 drupal_alter('pathologic', $url_params, $parts, $settings); // If any of the alter hooks asked us to just pass along the original URL, // then do so. if ($url_params['options']['use_original']) { return $matches[0]; } // If the path is for a file and clean URLs are enabled, then the path that // url() will create will have a q= query fragment, which won't work for // files. To avoid that, we use this trick to temporarily turn clean URLs on. // This is horrible, but it seems to be the sanest way to do this. // @see http://drupal.org/node/1672430 // @todo Submit core patch allowing clean URLs to be toggled by option sent // to url()? if (!empty($settings['is_file'])) { $settings['orig_clean_url'] = !empty($GLOBALS['conf']['clean_url']); if (!$settings['orig_clean_url']) { $GLOBALS['conf']['clean_url'] = TRUE; } } // Now for the url() call. Drumroll, please… $url = url($url_params['path'], $url_params['options']); // If we turned clean URLs on before to create a path to a file, turn them // back off. if ($settings['is_file'] && !$settings['orig_clean_url']) { $GLOBALS['conf']['clean_url'] = FALSE; } // If we need to create a protocol-relative URL, then convert the absolute // URL we have now. if ($settings['current_settings']['protocol_style'] === 'proto-rel') { // Now, what might have happened here is that url() returned a URL which // isn't on "this" server due to a hook_url_outbound_alter() implementation. // We don't want to convert the URL in that case. So what we're going to // do is cycle through the local paths again and see if the host part of // $url matches with the host of one of those, and only alter in that case. $url_parts = parse_url($url); if (!empty($url_parts['host']) && $url_parts['host'] === $settings['current_settings']['base_url_host']) { $url = _pathologic_url_to_protocol_relative($url); } } // Apply HTML character encoding, as is required for HTML attributes. // @see http://drupal.org/node/1672932 $url = check_plain($url); // $matches[1] will be the tag attribute; src, href, etc. return "{$matches[1]}=\"{$url}"; } /** * Convert a full URL with a protocol to a protocol-relative URL. * * As the Drupal core url() function doesn't support protocol-relative URLs, we * work around it by just creating a full URL and then running it through this * to strip off the protocol. * * Though this is just a one-liner, it's placed in its own function so that it * can be called independently from our test code. */ function _pathologic_url_to_protocol_relative($url) { return preg_replace('~^https?://~', '//', $url); } Det sociala ansvaret gör att vi måste utveckla SIA-Glass! | IHM

Det sociala ansvaret gör att vi måste utveckla SIA-Glass!

För att inspirera till ökad kompetensutveckling i svenskt näringsliv så fortsätter vi vår intervjuserie med människor och företag som valt att vända sig till IHM för att vässa sig och sin organisation.

I detta blogginlägg så träffar vi Stefan Carlsson, 47 år, marknads- & säljchef på det anrika företaget SIA Glass i Slöinge, som tillsammans med IHM har skapat SIA Glass Säljakademi. Så, över till Stefan.

– Hej Stefan, jättekul att få komma hit till Hallands glass-Mecka. Det ska bli spännande höra lite hur ni tänker kring socialt ansvar och företagets utveckling, men först lite kort om din bakgrund.

–  Hej, kul att du är här. Jag har jobbat inom livs i hela mitt yrkesliv, började som säljare på några bolag och har varit VD hos en fiskgrossist och Orkla Snacks. Jag är stolt Hallänning och bor på en hästgård inte långt härifrån tillsammans med fru och två barn. Utöver arbetet så är det familj och mycket idrott som gäller, gärna cykling, jag var med i cykellandslaget som junior. Var det tillräckligt kort? :-)

– Ja, föredömligt. När man tittar på er hemsida så pratar ni både om socialt ansvar och historiskt ansvar, kan du utveckla det?

– Gärna, jag är uppvuxen här i krokarna och naturligtvis har framgången med SIA Glass påverkat hela Slöinge, både genom arbetstillfällen och stolthet. Men det började långt tidigare, redan 1569 etablerades Berte Qvarn AB, som är början på koncernen, och har letts av 14 generationer Stenström, den 15:e generationen jobbar idag på SIA och nyligen så föddes också den 16:e som förhoppningsvis också blir en del av bolaget i framtiden.

I kraft av koncernens storlek och dess betydelse som arbetsgivare i området kom också ett stort ansvar, till exempel så betalade bolaget halva tandläkarkostnaden för sina anställdas barn långt innan den fria skoltandvården introducerades i Sverige. När slakteriet i Slöinge, den tidens största arbetsgivare, lades ner kring 1960 så bad de anställda Olof Stenström om hjälp. Olof som var ansvarig för familjens bolag, och aktiv inom politiken, funderade och fick till ett avtal med kommunen om att överta slakteriets gamla lokaler mot ett löfte om att skapa minst 12 årsanställda i Slöinge. Detta blev till slut, 1961, glassmejeriet SIA Glass med hjälp av Glass Oskar i Trollhättan och företaget har idag ca 160 anställda.

Några år efter starten blev frysen allt vanligare i hushållen och verksamheten växte. I början av 70-talet så åkte Olofs son Per (nuvarande ordförande i styrelsen) till USA och inspirerades, hemma igen så tog man beslut om att all SIA glass skulle vara gjord på grädde, levererad av traktens bönder, istället för vegetariskt fett som var vanligt då. Skopglass var också något han hade imponerats av, och efter USA-resan så myntades fyra ledstjärnor som genomsyrar bolaget än idag; Grädde, skopglass, inga konstiga ingredienser och Slöinge-jobb.

– Ni har växt stadigt genom åren men hur stora är ni idag?

– Ja, vi växer hela tiden och är idag tvåa på marknaden med en marknadsandel på ca 18,5% av dagligvaruhandeln, det är här man kan mäta och jämföra, men naturligtvis finns det idag även en stor handel utanför dagligvaruhandeln. Vi omsätter idag ungefär 410 miljoner och hade en tillväxt 2015 på 14%.

– Oj, bra tillväxt den kalla sommaren, hur kommer det sig?

– Vi var väldigt offensiva mot kedjorna och hade ett flertal lyckade kampanjer, vi är starka i dagligvaruhandeln och ca 75% av vår glass säljs via frysdiskarna i våra ovala paket.

– Och i vilka regioner är ni starkast?

– Stockholm, Halland och Skåne är vår topplista.

– Med era offensiva tankar förmodar jag att ni också satt upp nya mål?!

– Ja, det stämmer. 2020 ska vi ha ökat omsättningen till 600 miljoner och ha en marknadsandel på 25%, så offensiven fortsätter.

– Inga dåliga mål! Hur ser planen ut för att lyckas med så tuffa mål?

– Absolut tuffa mål! Och det är här IHM kommer in, för att ge stöd till vår säljkår genom öka kompetensnivån, även behålla- och attrahera nya medarbetare så beslutade vi oss för att skapa vår egen säljakademi tillsammans med IHM. Här kommer, under två år, ca 25 personer drillas i affärsmanaskap & ekonomi, retorik & förhandling, kommunikation & sociala medier och naturligtvis en aktiv säljträning, både i klassrummet och via era digitala utbildningsmoduler (det som vi på IHM kallar Blended Learning, min anmärkning). Vidare kommer deltagarna också att genomföra ett projektarbete under perioden och om allt går som det ska så blir man till slut IHM Diplomerad.

Vi kommer också att öka trycket på vår marknadsföring och ge oss in stort i fler regioner i Sverige. Så glass-Sverige får se upp :-)

– Ja, det låter härligt offensivt! Hur kommer det sig då att det blev IHM som utbildningspartner?

– Jag är själv Diplomerad Marknadsekonom (DIHM) på IHM och har också en MBA via ert samarbete med Henley. Så att IHM var en av de utbildningspartners vi diskuterade med kändes som självklart, att det slutligen också blev IHM är ett resultat av det upplägg ni presenterade. Det finns också en stor dragningskraft i varumärket som uppskattas av våra säljare, och det är viktigt för att de ska orka med en så här stor satsning.

– Och nu är ni igång, hur känns det?

– Ja, vi hade uppstart vecka 2 och säljarna är mycket positiva så det känns riktigt bra!

– Men hur ser marknaden ut, är den ökande eller ska ni ta stort från konkurrenter?

– Det är en kombination, naturligtvis vill vi ta marknadsandelar från våra konkurrenter men jag tror också att marknaden i stort har en potential att växa. Om vi tittar på USA ur ett konsumtionsmönsterperspektiv så ligger de på ca 20 liter per år och person, Sverige ligger bara på 11 liter.

– Är USA det största glass-landet, jag trodde det skulle vara Italien?

– Ja, USA är störst, och Italien är förvånansvärt litet även om de har väldigt god och bra glass. Anledningen till detta ser vi i hur man konsumerar glass i Italien, frysarna är i allmänhet små och därför sker handeln ofta direkt på gatan, man köper kanske bara en kula och njuter av i skuggan, så i Italien är det bara 4 liter per person och år. Här är vi mer lika amerikanerna med köp i dagligvaruhandeln och stora frysar hemma.

– Så, över till lite glassnörderi, vad är din absoluta favoritsmak?

– Oj, vilken svår fråga, jag äter glass fem dagar i veckan och smakar på väldigt många sorter men måste nog säga att vår mäktiga chokladtryffelglass Chocolate är en stor favorit.

– Och den äckligaste?

– Finns det äcklig glass? Förresten, jag smakade på ölglass i USA och det var inte något som föll mig i smaken.

– Men ni är ändå kända för att våga ta ut svängarna vad det gäller smaker, med bland annat pepparrotsglass för några år sedan, så ölglass vore väl värt en test?

– Vår produktutvecklingsavdelning består av två personer på heltid och de kommer fram med ca 80 smaker per år som vi testar internt, 20–30 av dessa når en testmarknad, åtminstone ut till vår butik här utanför, där vi testar hos våra konsumenter innan smakerna eventuellt går vidare ut på hela marknaden. Ölglass är inte aktuellt just nu men en av nyheterna i vårt pinnglasssortiment är en riktigt god whisky-glass. En annan nyhet bland pinnglassarna, som jag tror mycket på, är Kladdkaka. På skopglass-sidan är bland annat Popcorn en blivande storsäljare tror jag och den som vill testa något riktigt spännande bör pröva vår Rödbeta/Peppar.

– Då vill jag tacka för den här trevliga intervjun och så hoppas jag du kan förmedla ett tips till era utvecklare på en glass som jag gärna skulle prova, vad tror du om rosmaringlass?

– Spännande, den ska jag förmedla, men jag blir inte förvånad om de redan testat så den kanske kommer en dag. Tack själv, det var kul att du kom.

När jag åker därifrån så funderar jag på att vi på IHM får vara med och utveckla ett företag som startade i grunden redan 1569, är det Sveriges äldsta företag? Hemma sätter jag mig vid datorn och letar runt och det visar sig att Berte Qvarn är Sveriges sjätte äldsta fortfarande verksamma företag, stort.

Aludd

15 april 2016
Testa e-simuleringen här!

Kontakta mig, jag vill veta mer!

Tyvärr, formuläret är inte tillgängligt.
Läs mer om IHM Sales Performance B2B här!
Så här kan en simulering kan gå till